即使未“点击”,SwiftUI List ForEach 视图中的按钮也会触发?

zum*_*zum 6 ios swift swiftui

我有以下代码:

struct ButtonTapTest: View {
    
    let items = [1, 2, 3]
    
    var body: some View {
        
        List {
            ForEach(items, id:\.self) { item in
                CellTestView()
            }
        }
        
    }
}


struct CellTestView:View {
    
    
    var body: some View {
        
        VStack {
            
            Button {
                print("TOP")
            } label: {
                Image(systemName: "play.fill")
                    .font(.system(size: 40))
                    .foregroundColor(.red)
            }
            .border(.red)
            
            Spacer()
            
            Button {
                print("BOTTOM")
                
            } label: {
                Image(systemName: "play")
                    .font(.system(size: 40))
                    .foregroundColor(.red)
            }
            .border(.yellow)
            
        }
        
    }
    
}
Run Code Online (Sandbox Code Playgroud)

创建以下屏幕:

在此输入图像描述

问题:

无论我点击哪里,两个按钮操作都会在单元格中触发CellTestView。我希望单独的按钮操作单独触发,每个按钮操作仅在其按钮被点击时触发,而不是在我点击单元格上其他任何地方的外部时触发。

您可以在下面的 gif 中看到,无论我在哪里点击CellTestView,两个按钮操作都会被触发,无论我在视图的哪里点击,并且“顶部”和“底部”日志都会同时触发。

如何解决此问题,以便单元格中的两个按钮独立接收点击,并且仅当点击位于相关按钮内部时?

在此输入图像描述

ahe*_*eze 17

当列表行中有多个按钮时,您需要手动将按钮样式设置为.borderless.plain。这是因为按钮 \xe2\x80\x9cadapt\xe2\x80\x9d 到其上下文。\n根据文档

\n
\n

如果您在容器内创建按钮(例如List ),则样式将解析为该容器内针对该特定平台的按钮的推荐样式。

\n
\n

因此,当您的按钮位于列表中时,其点击目标会扩展以填充该行,并且您会获得突出显示的动画。当你有超过 2 个按钮时,SwiftUI 不够智能,无法阻止这种副作用,因此你需要buttonStyle手动设置。

\n
CellTestView()\n    .buttonStyle(.borderless)\n
Run Code Online (Sandbox Code Playgroud)\n

结果:

\n

点击顶部和底部按钮会产生单独的打印语句

\n

  • 那么,这是为什么呢?我想了解其工作原理。我们是否需要始终使用“.buttonStyle(.borderless)”修饰符修改单元格视图才能使按钮正常工作,或者这是一个例外?您能详细说明为什么会这样吗? (3认同)