只有当父 VStack 位于 SwiftUI 中的 List 内时,才会触发 Buttons 的多个动作处理程序

moh*_*wal 5 xcode ios swiftui

情况 1:- 当我在 VStack 中有多个按钮时,单击其中任何一个按钮时,两个按钮的动作处理程序都会立即执行,仅当 VStack 是 List 的子项时才会发生这种情况。例如-

List {
            VStack {
                Button(action: { print("A") }) {
                Text("Button A")
                }

                Button(action: { print("B") }) {
                Text("Button B")
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

在这里,当您单击任何一个按钮(例如按钮 B)时,o/p 是:- A B

案例 2 :- 尝试只使用 VStack,它工作正常。例如-

VStack {
            Button(action: { print("C") }) {
            Text("Button C")
            }

            Button(action: { print("D") }) {
            Text("Button D")
            }
        }
Run Code Online (Sandbox Code Playgroud)

在这里,当您单击任何一个按钮(例如按钮 D)时,o/p 是:- D

我是 iOS 编程的新手,请帮助我了解我哪里出错了还是 SwiftUI 的问题?

Ant*_*ton 5

将按钮样式设置为与默认不同的样式,例如 BorderlessButtonStyle()

struct Test: View {
  var body: some View {
    NavigationView {
      List {
        ForEach([
          "Line 1",
          "Line 2",
        ], id: \.self) {
          item in
          HStack {
            Text("\(item)")
            Spacer()
            Button(action: { print("\(item) 1")}) {
              Text("Button 1")
            }
            Button(action: { print("\(item) 2")}) {
              Text("Button 2")
            }
          }
        }
        .onDelete { _ in }
        .buttonStyle(BorderlessButtonStyle())
      }
      .navigationBarItems(trailing: EditButton())
    }
    .accentColor(.red)
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,我测试了你的建议以及其他一些“ButtonStyles”,发现只有“DefaultButtonStyle”有这个问题。如果我们将其他样式应用于按钮,它就可以正常工作。仍然不确定这是一个错误还是预期的行为。不过谢谢。 (2认同)

kon*_*iki 2

列表内的按钮将无法按预期工作。很可能是一个错误,但官方并未承认。由于没有得到承认,没有人知道它何时/是否会被修复。

与此同时,您可以使用自定义按钮,如下所示。它复制了按钮行为(点击时颜色和变暗):

struct ContentView: View {
    @State private var flag = false

    var body: some View {
        List {
            VStack {
                MyButton(label: "Button A") {
                    print("A")
                }

                MyButton(label: "Button B") {
                    print("B")
                }
            }
        }
    }
}

struct MyButton: View {
    @State private var tapped = false
    let label: String
    let action: () -> ()

    var body: some View {
        let g = DragGesture(minimumDistance: 0, coordinateSpace: .local)
            .onChanged({ _ in
                withAnimation { self.tapped = true }
            })
            .onEnded({ _ in
                withAnimation { self.tapped = false }
                self.action()
            })

        return Text(label)
            .foregroundColor(Color(UIColor.link)
                .opacity(tapped ? 0.5 : 1.0))
            .gesture(g)


    }
}
Run Code Online (Sandbox Code Playgroud)