SwiftUI按钮仅在文本部分上点击

时间:2019-08-02 21:20:49

标签: swiftui

我按钮的背景区域未检测到用户交互。与该按钮交互的唯一方法是点击按钮的“文本/标签”区域。如何使整个Button可轻敲?

struct ScheduleEditorButtonSwiftUIView: View {

    @Binding  var buttonTagForAction : ScheduleButtonType
    @Binding  var buttonTitle        : String
    @Binding  var buttonBackgroundColor : Color


    let buttonCornerRadius = CGFloat(12)

    var body: some View {

        Button(buttonTitle) {
              buttonActionForTag(self.buttonTagForAction)
        }.frame(minWidth: (UIScreen.main.bounds.size.width / 2) - 25, maxWidth: .infinity, minHeight: 44)

                            .buttonStyle(DefaultButtonStyle())
                            .lineLimit(2)
                            .multilineTextAlignment(.center)
                            .font(Font.subheadline.weight(.bold))
                            .foregroundColor(Color.white)

                            .border(Color("AppHighlightedColour"), width: 2)
                           .background(buttonBackgroundColor).opacity(0.8)

                            .tag(self.buttonTagForAction)
                            .padding([.leading,.trailing], 5)
       .cornerRadius(buttonCornerRadius)

    }
}

5 个答案:

答案 0 :(得分:7)

您可以通过添加修饰符来定义用于命中测试的内容形状:contentShape(_:eoFill:)

重要的是你必须在 Button 的内容中应用。

True
>>> 

另一个

Button(action: {}) {
    Text("Select file")
       .frame(width: 300)
       .padding(100.0)
       .foregroundColor(Color.black)
       .contentShape(Rectangle()) // Add this line
}
.background(Color.green)
.cornerRadius(4)
.buttonStyle(PlainButtonStyle())

答案 1 :(得分:1)

这可以解决我的问题:

var body: some View {
    GeometryReader { geometry in
        Button(action: {
            // Action
        }) {
            Text("Button Title")
                .frame(
                    minWidth: (geometry.size.width / 2) - 25,
                    maxWidth: .infinity, minHeight: 44
                )
                .font(Font.subheadline.weight(.bold))
                .background(Color.yellow).opacity(0.8)
                .foregroundColor(Color.white)
                .cornerRadius(12)

        }
        .lineLimit(2)
        .multilineTextAlignment(.center)
        .padding([.leading,.trailing], 5)
    }
}

button

您是否有理由使用UIScreen而不是GeometryReader

答案 2 :(得分:1)

我认为这是一个更好的解决方案,将.frame值添加到Text()上,按钮将覆盖整个区域?

Button(action: {
    //code
}) {
    Text("Click Me")
    .frame(minWidth: 100, maxWidth: .infinity, minHeight: 44, maxHeight: 44, alignment: .center)
    .foregroundColor(Color.white)
    .background(Color.accentColor)
    .cornerRadius(7)
}

答案 3 :(得分:1)

答案来得有点晚,但是我发现了两种方法可以做到这一点-

选项1:使用几何读取器

Button(action: {
}) {
    GeometryReader { geometryProxy in
        Text("Button Title")
            .font(Font.custom("SFProDisplay-Semibold", size: 19))
            .foregroundColor(Color.white)
            .frame(width: geometryProxy.size.width - 20 * 2) // horizontal margin
            .padding([.top, .bottom], 10) // vertical padding
            .background(Color.yellow)
            .cornerRadius(6)
    }
}

选项2:将HStack与垫片一起使用

HStack {
    Spacer(minLength: 20) // horizontal margin
    Button(action: {

    }) {
        Text("Hello World")
            .font(Font.custom("SFProDisplay-Semibold", size: 19))
            .frame(maxWidth:.infinity)
            .padding([.top, .bottom], 10) // vertical padding
            .background(Color.yellow)
            .foregroundColor(Color.white)
            .cornerRadius(6)
    }
    Spacer(minLength: 20)
}.frame(maxWidth:.infinity)

我在这里的思考过程是,尽管选项1更简洁,但我会选择选项2,因为它与父级的大小(通过GeometryReader的耦合较小,并且更符合我认为SwiftUI的使用方式) HStackVStack

答案 4 :(得分:1)

正确的解决方案是使用.contentShape() API。

Button(action: action) {
  HStack {
    Spacer()
    Text("My button")
    Spacer()
  }
}
.contentShape(Rectangle())

您可以更改提供的形状以匹配按钮的形状;如果您的按钮是RoundedRectangle,则可以提供它。