将包含 link 作为变量的 SwiftUI 2.0 ReusableView

SwiftUI 2.0 ReusableView that will contain a link as a variable

我正在开发一个包含运动列表的应用程序,我为运动的名称和图像构建了一个可重复使用的视图,用于列出每项运动。然后我为每项运动创建了一个视图,当用户从运动列表中点击运动图像时,我为图像、运动名称和 link 创建了一个变量,我不知道如何 link a带有 NavigationLink 的变量。我在这里迷路了,任何帮助将不胜感激。下面是我的代码。

struct SportTypeInsetView: View {
var buttonImage1: String
var buttonName1: String
var buttonLink1: String
var body: some View {
VStack {
NavigationView {
VStack {
  Button (action: {
                        
}) {
  Image(buttonImage1)
   .resizable()
   .clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
    }
     .frame(width: 50, height: 30)
                
    Text(buttonName1)
    .font(.footnote)
    .foregroundColor(.primary)
    .multilineTextAlignment(.leading)
     .lineLimit(1)
       }
      }
    }
   } 
}

SportTypeInsetView(buttonImage1: "瑜伽图标", buttonName1: "瑜伽",buttonLink1: )

点击按钮时如何将它连接到 YogaView()?

谢谢。

最简单的方法是将 Button 替换为 NavigationLink。在 NavigationLink 中,您将一个视图 (YogaView) 传递给它,您可以像任何其他视图一样为其提供参数。这是一个例子:

struct ContentView : View {
    var body: some View {
        SportTypeInsetView(buttonImage1: "0", buttonName1: "Button", buttonLink1: "Link")
    }
}

struct SportTypeInsetView: View {
    var buttonImage1: String
    var buttonName1: String
    var buttonLink1: String
    
    var body: some View {
        VStack {
            NavigationView {
                VStack {
                    NavigationLink(destination: YogaView(linkName: buttonLink1)) {
                        Image(buttonImage1)
                            .resizable()
                            .clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
                            .frame(width: 50, height: 30)
                    }
                    
                    Text(buttonName1)
                        .font(.footnote)
                        .foregroundColor(.primary)
                        .multilineTextAlignment(.leading)
                        .lineLimit(1)
                }
            }
        }
    }
}

struct YogaView : View {
    var linkName : String
    
    var body: some View {
        Text(linkName)
    }
}

如果您真的想用一个按钮来实现,您可以使用 NavigationLinkisActive 属性 和一个@State变量:

struct SportTypeInsetView: View {
    var buttonImage1: String
    var buttonName1: String
    var buttonLink1: String
    
    @State private var linkActive = false
    
    var body: some View {
        VStack {
            NavigationView {
                VStack {
                    Button(action: { linkActive = true }) {
                        Image(buttonImage1)
                            .resizable()
                            .clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
                            .frame(width: 50, height: 30)
                    }
                    .overlay(
                        NavigationLink(destination: YogaView(linkName: buttonLink1), isActive: $linkActive) {
                            EmptyView()
                        })
                    
                    Text(buttonName1)
                        .font(.footnote)
                        .foregroundColor(.primary)
                        .multilineTextAlignment(.leading)
                        .lineLimit(1)
                }
            }
        }
    }
}

您可以将 NavigationLink 与按钮样式一起使用 DefaultButtonStyle

NavigationLink 有一个标签参数,它基本上是一个 SwiftUI 视图对象,您可以简单地传递一个 Text 对象,使其看起来像按钮,或者同时传递 ImageText ,由您决定,最终结果将是按钮样式 NavigationLink.

提供按钮样式有助于给您类似按钮的感觉。

NavigationLink(destination: SportDetailView(),
               label: {
                        Text("Navigate To next Screen")
             }).buttonStyle(DefaultButtonStyle())

如果您想自定义 NavigationLink 标签视图,您可以这样做。

  NavigationLink(destination: SportDetailView(),
                 label: {
                           HStack {
                               Image(systemName: "pencil")
                               Text("Edit name")
                           }
               }).buttonStyle(DefaultButtonStyle())

要实现行为动态的导航 link,SportTypeInsetView 可以有一个通用类型 TargetView,它受 View 协议约束。

话虽如此,您不需要 buttonLink1,因为 targetView 本身是动态的。

ex: 
SportTypeInsetView(targetView: YogaView(), buttonImage1: "Tap", buttonName1: "Button A", buttonLink1: "")

ex:
SportTypeInsetView(targetView: SomeAnotherSportView(), buttonImage1: "Tap", buttonName1: "Button B", buttonLink1: "")
struct SportTypeInsetView<TargetView: View>: View {

    let targetView: TargetView
    var buttonImage1: String
    var buttonName1: String
    var buttonLink1: String
    
    var body: some View {
        VStack {
            NavigationView {
                VStack {
                    NavigationLink(
                        destination: self.targetView,
                        label: {
                            //Add Image , text or button here
                            Text("Navigation to next")
                        }).buttonStyle(DefaultButtonStyle())
                    
                    
                    Text(buttonName1)
                        .font(.footnote)
                        .foregroundColor(.secondary)
                        .multilineTextAlignment(.leading)
                        .lineLimit(1)
                }
            }
        }
    }
}