宽度为0的swiftUI按钮仍处于活动状态

时间:2020-03-14 12:54:31

标签: swiftui

我将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
}

3 个答案:

答案 0 :(得分:2)

代替复杂的“停用”,只需使用真正的删除,如下所示

    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

答案 1 :(得分:2)

有一个非常简单的解释。

尝试下一个代码段

  public static void setImageViewWithByteArray(ImageView view, Byte[] data) {
        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
        view.setImageBitmap(bitmap);
    }

enter image description here

为什么?

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

被定义为View的函数,它返回另一个View,作为任何一种View修饰符。如预期的那样,生成的View具有.zero大小的框架。

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

.frame(..) 

enter image description here

只需在文本视图中添加.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)
            Rectangle()
                .fill(Color.green)
                .frame(width: 100, height: 100)
                .blendMode(.exclusion)
        }
    }
}

和文本“消失enter image description here” ...

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

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)
        }
    }
}

您会看到,仍然有一些对点击手势敏感的“不可见”区域

enter image description here

答案 2 :(得分:1)

您可以通过添加.disabled(self.zeroWidth)

来禁用按钮
Button(action: { self.leftButtons[i].action() }) {
    ButtonLabel( singleline: false,
                buttonAttr: self.leftButtons[i]
    )
        .padding(0)
       //.background(Color.green)  // not visible
}
.disabled(self.zeroWidth)
.buttonStyle(BorderlessButtonStyle())
.frame( width: self.zeroWidth ? 0 : 100, height: 50)
.background(Color.green)
.clipped()
.foregroundColor(Color.white)
.padding(0)

enter image description here

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

相关问题