SwiftUI-列表行中的多个按钮

Bra*_*key 14 ios swift swiftui

假设我List在一行中有一个和两个按钮,如何在不突出显示整个行的情况下区分哪个按钮被轻拍了?

对于此示例代码,当点击该行中的任何一个按钮时,将同时调用两个按钮的动作回调。

// a simple list with just one row
List {

    // both buttons in a HStack so that they appear in a single row
    HStack {
        Button(action: {
            print("button 1 tapped")
        }) {
            Text("One")
        }

        Button(action: {
            print("button 2 tapped")
        }) {
            Text("Two")
        }
    }
}

// when tapping just once on either button:
// "button 1 tapped"
// "button 2 tapped"
Run Code Online (Sandbox Code Playgroud)

Ram*_*mis 103

您需要使用BorderlessButtonStyle()PlainButtonStyle()

    List([1, 2, 3], id: \.self) { row in
        HStack {
            Button(action: { print("Button at \(row)") }) {
                Text("Row: \(row) Name: A")
            }
            .buttonStyle(BorderlessButtonStyle())
            
            Button(action: { print("Button at \(row)") }) {
                Text("Row: \(row) Name: B")
            }
            .buttonStyle(PlainButtonStyle())
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • @Jessy 在文档中花费了大量时间。 (7认同)
  • 很有魅力,但为什么呢? (6认同)
  • 是的。这对我来说是真正的WTAF。你是怎么发现这一点的? (5认同)
  • 如果您需要维护按钮动画(突出显示等),这是最好的解决方案 (4认同)
  • 出色的。即使所有行上都有一个 NavigationLink,它也能完美地工作。 (2认同)

Mat*_*ini 14

似乎是有关Button何时包含在List一行中的特定问题。

解决方法

List {
  HStack {
    Text("One").tapAction { print("One") }
    Text("Two").tapAction { print("Two") }
  }
}
Run Code Online (Sandbox Code Playgroud)

这将产生所需的输出。

您也可以使用a Group代替Text“按钮”的复杂设计。

  • 不幸的是,这个错误不仅限于列表中的按钮。我能够在 HStack 内的列表内使用多个 NavigationLink 重现相同的问题。 (2认同)

小智 7

与 SwiftUI 的不同之处之一是您没有创建特定实例,例如 UIButton,因为您可能在 Mac 应用程序中。使用 SwiftUI,您请求的是按钮类型的东西。

在这种情况下,由于您位于列表行中,系统会为您提供完整尺寸,点击任意位置以触发操作,按钮。并且由于您添加了其中的两个,因此当您点击任意位置时都会触发它们。

您可以添加两个单独的视图并给它们一个.onTapGesture,让它们基本上充当按钮,但是您将失去单元格行的点击闪烁和任何其他自动按钮,如 SwiftUI 将提供的功能。

List {
    HStack {
        Text("One").onTapGesture {
            print("Button 1 tapped")
        }

        Spacer()

        Text("Two").onTapGesture {
            print("Button 2 tapped")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • tapAction 不再可用(Xcode 11.2 beta)。使用 .onTapGesture() (5认同)

Ant*_*ton 6

您需要创建自己的 ButtonStyle:

  struct MyButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
      configuration.label
        .foregroundColor(.accentColor)
        .opacity(configuration.isPressed ? 0.5 : 1.0)
    }
  }

  struct IdentifiableString: Identifiable {
    let text: String
    var id: String { text }
  }

  struct Test: View {
    var body: some View {
      List([
        IdentifiableString(text: "Line 1"),
        IdentifiableString(text: "Line 2"),
      ]) {
        item in
        HStack {
          Text("\(item.text)")
          Spacer()
          Button(action: { print("\(item.text) 1")}) {
            Text("Button 1")
          }
          Button(action: { print("\(item.text) 2")}) {
            Text("Button 2")
          }
        }
      }.buttonStyle(MyButtonStyle())
    }
  }
Run Code Online (Sandbox Code Playgroud)

  • 实际上,您不需要自定义样式。只需使用“BorderlessButtonStyle()” (2认同)