如何修复在 ForEach 循环中不可点击的按钮?

问题描述

我有一个包含按钮的视图。带有按钮的视图是从 forEach 循环创建的。出于某种原因,只有某些按钮可以点击,而其他按钮则不能。

父视图包含 NavigationView、NavigationView 内部的滚动视图、滚动视图内部的 lazyvstack、lazyvstack 中的 forEachloop,在该 for 循环中是包含按钮的子视图。

struct ContentView: View {

  let peoples:[Person] = Bundle.main.decode("data.json")

  var body: some View {
    let columns = [
      GridItem(.flexible(minimum: 300),spacing: 10)
    ]

    NavigationView {
      ScrollView(.vertical) {
        Lazyvstack {
          ForEach(peoples,id: \.self) { person in
            PersonView(name: person.Name,age: person.Age)
          }
        }
        .navigationTitle("A list of people")
        .navigationViewStyle(DefaultNavigationViewStyle())
        .padding()
      }
    }
  }
}

子视图如下。我怀疑滚动视图正在窃取用户输入,但我不确定为什么或如何克服它。有些按钮是可贴胶带的,有些则不是。

struct PersonView: View {

  @Environment(\.colorScheme) var colorScheme

  var name: String
  var age: Int

  var body: some View {
    vstack(alignment:.leading) {
      Image("randoPerson")
        .resizable()
        .scaledToFill()
        .frame(minWidth: nil,idealWidth: nil,maxWidth: UIScreen.main.bounds.width,minHeight: nil,idealHeight: nil,maxHeight: 300,alignment: .center)
        .clipped()
      vstack(alignment: .leading,spacing: 6) {
        Text("name")
          .fontWeight(.heavy)
          .padding(.leading)

        Text("Age \(age)")
          .foregroundColor(Color.gray)
          .padding([.leading,.bottom])


        Button(action: { print("I was tapped") }) {
          HStack {
            Image(systemName: "message.fill")
              .font(.title)
              .foregroundColor(.white)
              .padding(.leading)

            Text("Message them")
              .font(.subheadline)
              .foregroundColor(.white)
              .padding()
          }
          .background(Color.blue)
        }
        .padding()
      }
      .background(Color(UIColor.systemBackground).cornerRadius(15))
      .shadow(color:colorScheme == .dark
                ? Color.white.opacity(0.2)
                : Color.black.opacity(0.2),radius: 7,x: 0,y: 2)
    }
  }
}

解决方法

要解决此问题,您可以添加一个与 id: UUID 关联的 Person,并使用其 ID 在 Person 内的 ForEach 之间进行迭代。

您还会注意到我将值添加为小写字母以遵守 Swift 约定。

struct Person {

  let id: UUID // Add this value
  var name: String
  var age: Int
}

所以这里是用 id 替换 \.self 的 ContentView:

struct ContentView: View {

  let peoples: [Person] = Bundle.main.decode("data.json")

  var body: some View {
    NavigationView {
      ScrollView(.vertical) {
        LazyVStack {
          ForEach(peoples,id: \.id) { person in  // id replace \.self here
            PersonView(name: person.name,age: person.age)  // removed uppercase
          }
        }
        .navigationTitle("A list of people")
        .navigationViewStyle(DefaultNavigationViewStyle())
        .padding()
      }
    }
  }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...