SwiftUI 按钮仅点击文本部分

Rya*_*TCB 44 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)

    }
}
Run Code Online (Sandbox Code Playgroud)

Lor*_*o R 48

我认为这是一个更好的解决方案,将.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)
}
Run Code Online (Sandbox Code Playgroud)

  • 这不适用于 Xcode 11.5 beta。我尝试了两种方法,一种是答案中的方法,另一种是将大小移动到自定义 ButtonStyle (3认同)
  • 很好的修复,很有意义。 (2认同)

Dan*_*rwe 29

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

Button(action: action) {
  HStack {
    Spacer()
    Text("My button")
    Spacer()
  }
}
.contentShape(Rectangle())
Run Code Online (Sandbox Code Playgroud)

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

  • 将 .contentShape(Rectangle()) 添加到按钮内的 HStack 对我有用 (12认同)
  • 这是唯一对我有用的解决方案,除了我必须将其放在按钮内的堆栈上,而不是放在按钮本身上。 (4认同)
  • 是的,这就是真正的答案,无论您是否有背景颜色,它都有效。 (2认同)
  • 如果您使用自定义 ButtonStyle,则其他解决方案不起作用。这才是问题的真正解决方案。 (2认同)

kga*_*dis 22

简答

确保Text(或按钮内容)跨越触摸区域的长度,并使用.contentShape(Rectangle())

Button(action:{}) {
  HStack {
    Text("Hello")
    Spacer()
  }
  .contentShape(Rectangle())
}
Run Code Online (Sandbox Code Playgroud)

长答案

有两部分:

  1. 需要拉伸的内容(例如TextButton
  2. 命中测试需要考虑的内容

拉伸内容(例如Text):

// Solution 1 for stretching content
HStack {
  Text("Hello")
  Spacer()
}

// Solution 2 for stretching content
Text("Hello")
  .frame(maxWidth: .infinity, alignment: .leading)

// Alternatively, you could specify a specific frame for the button.
Run Code Online (Sandbox Code Playgroud)

要考虑用于命中测试的内容,请使用.contentShape(Rectangle())

// Solution 1
Button(action:{}) {
  HStack {
    Text("Hello")
    Spacer()
  }
  .contentShape(Rectangle())
}

// Solution 2
Button(action:{}) {
  Text("Hello")
    .frame(maxWidth: .infinity, alignment: .leading)
    .contentShape(Rectangle())
}
Run Code Online (Sandbox Code Playgroud)


bac*_*h-f 19

这解决了我的问题:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

按钮

你有什么理由使用UIScreen而不是GeometryReader吗?

  • 不知道 GeometryReader。感谢您提供的信息,我将阅读它 (3认同)

Lal*_*hna 10

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

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

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())
Run Code Online (Sandbox Code Playgroud)

其他

Button(action: {}) {
    VStack {
       Text("Select file")
           .frame(width: 100)
       Text("Select file")
           .frame(width: 200)
    }
    .contentShape(Rectangle())
}
.background(Color.green)
.cornerRadius(4)
.buttonStyle(PlainButtonStyle())
Run Code Online (Sandbox Code Playgroud)


Has*_*ved 5

你可能会这样做:

Button { /*to do something on button click*/} 
label: { Text("button text").foregroundColor(Color.white)}
.frame(width: 45, height: 45, alignment: .center)
.background(Color.black)
Run Code Online (Sandbox Code Playgroud)

解决方案:

Button(action: {/*to do something on button click*/ }) 
{ 
HStack { 
Spacer()
Text("Buttton Text")
Spacer() } }
.frame(width: 45, height: 45, alignment: .center)
.foregroundColor(Color.white)
.background(Color.black).contentShape(Rectangle())
Run Code Online (Sandbox Code Playgroud)