Swiftui 宽度为0的快捷键处于活动状态

Swiftui 宽度为0的快捷键处于活动状态,swiftui,Swiftui,我将SwiftUI按钮的宽度设置为0以禁用它。 如果按钮的with设置为0,则该按钮将按预期消失,但单击黄色堆栈的左边缘将激活该按钮。 为什么会发生这种情况? 我怎样才能避免呢 struct ContentView: View { @State var zeroWidth = false var body: some View { VStack{ ButtonLine( leftButtons: [ButtonAttr( label: "LB1",

我将SwiftUI按钮的宽度设置为0以禁用它。 如果按钮的with设置为0,则该按钮将按预期消失,但单击黄色堆栈的左边缘将激活该按钮。 为什么会发生这种情况? 我怎样才能避免呢

struct ContentView: View {
  @State var zeroWidth = false

  var body: some View {
    VStack{
      ButtonLine( leftButtons: [ButtonAttr( label: "LB1",
                                            action: {print("LB1")},
                                            iconSystemName : "person"
                                          )],
                                 zeroWidth: zeroWidth
                  )
      Button("Toggle width \(zeroWidth ? "On" : "Off" ) "){ self.zeroWidth.toggle() }
    }
  }
}

struct ButtonLine: View {
  let leftButtons : [ButtonAttr]
  let zeroWidth : Bool

  var body: some View {

    HStack(spacing: 0) {
      ForEach(leftButtons.indices, id: \.self)
      { i in
        HStack(spacing: 0.0)
        {
          Button(action: { self.leftButtons[i].action() }) {
            ButtonLabel( singleline: false,
                         buttonAttr: self.leftButtons[i]
            )
            .padding(0)
            //.background(Color.green)  // not visible
          }
         .buttonStyle(BorderlessButtonStyle())
            .frame( width: self.zeroWidth ? 0 : 100, height: 50) 
         .background(Color.green)
         .clipped()
         .foregroundColor(Color.white)
         .padding(0)
        }
        // .background(Color.blue)   // not visible
      }
      // .background(Color.blue)   // not visible
      Spacer()
      Text("CONTENT")
      .background(Color.green)
      .onTapGesture {
        print("Content tapped")
      }
      Spacer()
    }
    .background(Color.yellow)
      .onTapGesture {
        print("HS tapped")
    }
  }
}

struct ButtonLabel: View {
  var singleline : Bool
  var buttonAttr : ButtonAttr
  var body: some View {
    VStack (spacing: 0.0) {
      Image(systemName: buttonAttr.iconSystemName).frame(height: singleline ? 0 : 20).clipped()
      .padding(0)
      .background(Color.blue)
      Text(buttonAttr.label)
      .padding(0)
      .background(Color.blue)
    }
    .padding(0)
    .background(Color.red)
  }
}

struct ButtonAttr
{   let label : String
    let action: ()-> Void
    let iconSystemName : String
}

您可以通过添加.disabledself.zeroWidth来禁用按钮

您可以通过单击xcode中的图标调试视图层次结构:

您可以通过添加.disabledself.zeroWidth来禁用按钮

您可以通过单击xcode中的图标调试视图层次结构:

不用复杂的停用,只需使用真正的移除,如下所示

    HStack(spacing: 0.0)
    {
        if !self.zeroWidth {
            Button(action: { self.leftButtons[i].action() }) {
                ButtonLabel( singleline: false,
                             buttonAttr: self.leftButtons[i]
                )
                    .padding(0)
                //.background(Color.green)  // not visible
            }
            .buttonStyle(BorderlessButtonStyle())
            .frame(width: 100, height: 50)
            .background(Color.green)
            .clipped()
            .foregroundColor(Color.white)
            .padding(0)
        }
    }.frame(height: 50) // to keep height persistent

不要使用复杂的去激活,只需使用真正的移除,如下所示

    HStack(spacing: 0.0)
    {
        if !self.zeroWidth {
            Button(action: { self.leftButtons[i].action() }) {
                ButtonLabel( singleline: false,
                             buttonAttr: self.leftButtons[i]
                )
                    .padding(0)
                //.background(Color.green)  // not visible
            }
            .buttonStyle(BorderlessButtonStyle())
            .frame(width: 100, height: 50)
            .background(Color.green)
            .clipped()
            .foregroundColor(Color.white)
            .padding(0)
        }
    }.frame(height: 50) // to keep height persistent

有一个非常简单的解释

请尝试下一个代码段

struct ContentView: View {
    var body: some View {
        Text("Hello").padding().border(Color.yellow).fixedSize().frame(width: 0)
    }
}
为什么?

定义为视图的函数,返回另一个视图,作为任何类型的视图修改器。结果视图的帧大小为.0,如预期的那样

这是真的吗?让我们检查一下

struct ContentView: View {
    var body: some View {
        HStack(spacing: 0) {
            Rectangle()
                .fill(Color.orange)
                .frame(width: 100, height: 100)
            Text("Hello")
                .padding()
                .border(Color.black)
                .fixedSize()
                .frame(width: 0, height: 0)
            Rectangle()
                .fill(Color.green)
                .frame(width: 100, height: 100)
                .blendMode(.exclusion)
        }
    }
}
只需将.clipped修改器添加到文本视图中即可

struct ContentView: View {
    var body: some View {
        HStack(spacing: 0) {
            Rectangle()
                .fill(Color.orange)
                .frame(width: 100, height: 100)
            Text("Hello")
                .padding()
                .border(Color.black)
                .fixedSize()
                .frame(width: 0, height: 0)
                .clipped()
            Rectangle()
                .fill(Color.green)
                .frame(width: 100, height: 100)
                .blendMode(.exclusion)
        }
    }
}
文本消失了

它将从屏幕上消失,但不会从视图层次结构中消失!。再次更改代码

struct ContentView: View {
    var body: some View {
        HStack(spacing: 0) {
            Rectangle()
                .fill(Color.orange)
                .frame(width: 100, height: 100)
            Text("Hello")
                .padding()
                .border(Color.black)
                .fixedSize().onTapGesture {
                    print("tap")
                }
                .frame(width: 0, height: 0)
                .clipped()
            Rectangle()
                .fill(Color.green)
                .frame(width: 100, height: 100)
                .blendMode(.exclusion)
        }
    }
}
你看,仍然有一些无形的区域对轻触动作敏感


有一个非常简单的解释

请尝试下一个代码段

struct ContentView: View {
    var body: some View {
        Text("Hello").padding().border(Color.yellow).fixedSize().frame(width: 0)
    }
}
为什么?

定义为视图的函数,返回另一个视图,作为任何类型的视图修改器。结果视图的帧大小为.0,如预期的那样

这是真的吗?让我们检查一下

struct ContentView: View {
    var body: some View {
        HStack(spacing: 0) {
            Rectangle()
                .fill(Color.orange)
                .frame(width: 100, height: 100)
            Text("Hello")
                .padding()
                .border(Color.black)
                .fixedSize()
                .frame(width: 0, height: 0)
            Rectangle()
                .fill(Color.green)
                .frame(width: 100, height: 100)
                .blendMode(.exclusion)
        }
    }
}
只需将.clipped修改器添加到文本视图中即可

struct ContentView: View {
    var body: some View {
        HStack(spacing: 0) {
            Rectangle()
                .fill(Color.orange)
                .frame(width: 100, height: 100)
            Text("Hello")
                .padding()
                .border(Color.black)
                .fixedSize()
                .frame(width: 0, height: 0)
                .clipped()
            Rectangle()
                .fill(Color.green)
                .frame(width: 100, height: 100)
                .blendMode(.exclusion)
        }
    }
}
文本消失了

它将从屏幕上消失,但不会从视图层次结构中消失!。再次更改代码

struct ContentView: View {
    var body: some View {
        HStack(spacing: 0) {
            Rectangle()
                .fill(Color.orange)
                .frame(width: 100, height: 100)
            Text("Hello")
                .padding()
                .border(Color.black)
                .fixedSize().onTapGesture {
                    print("tap")
                }
                .frame(width: 0, height: 0)
                .clipped()
            Rectangle()
                .fill(Color.green)
                .frame(width: 100, height: 100)
                .blendMode(.exclusion)
        }
    }
}
你看,仍然有一些无形的区域对轻触动作敏感


Thnx!很好的解决方案,我会使用它,但我的理解是:原因是什么,为什么0-width按钮仍然处于活动状态?@mica,我们不知道SwiftUI的内部实现,但0-width可能不会删除跟踪rect,因此活动元素处理事件仍然存在。无论如何这样的东西是不可靠的,即使它现在可以工作,它可能会在下一个版本中停止,反之亦然。Thnx!很好的解决方案,我会使用它,但我的理解是:原因是什么,为什么0-width按钮仍然处于活动状态?@mica,我们不知道SwiftUI的内部实现,但0-width可能不会删除跟踪rect,因此活动元素处理事件仍然存在。无论如何这样的东西是不可靠的,即使它现在可以工作,它可能会在下一个版本中停止,反之亦然。Thnx!这也是一个很好的解决方案,但就我的理解,你知道吗,为什么0-width按钮仍然处于活动状态?@mica,因为它仍然是视图层次结构的一部分。我确实编辑了我的文章,以显示视图层次结构,并向您展示如何自己调试它。为什么它仍然是层次结构的一部分,即使它没有宽度,我也不知道。Thnx!这也是一个很好的解决方案,但就我的理解,你知道吗,为什么0-width按钮仍然处于活动状态?@mica,因为它仍然是视图层次结构的一部分。我确实编辑了我的文章,以显示视图层次结构,并向您展示如何自己调试它。我不知道为什么即使它没有宽度,它仍然是等级制度的一部分。