这是可以做到的一种方法。有一个带有两个重叠白色矩形的按钮。只有红色区域可以点击:
struct ContentView: View {
var body: some View {
HStack(spacing: 0) {
Spacer()
Button(action: {}) {
Text("This is one big button")
.frame(width: 200, height: 200)
.background(Color.red)
}
.overlay(
HStack {
Spacer()
VStack {
Rectangle()
.frame(width: 100, height: 50)
.foregroundColor(.white)
Spacer()
Rectangle()
.frame(width: 100, height: 50)
.foregroundColor(.white)
}
}
)
Spacer()
}
}
}
使用自定义形状的解决方案
另一种方法是为Button 创建一个自定义Shape,然后用它来绘制和设置它的contentShape():
struct ButtonShape: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
let width = rect.width
let height = rect.height
path.move(to: CGPoint(x: 0, y: 0))
path.addLine(to: CGPoint(x: width/2, y: 0))
path.addLine(to: CGPoint(x: width/2, y: height/4))
path.addLine(to: CGPoint(x: width, y: height/4))
path.addLine(to: CGPoint(x: width, y: 3 * height/4))
path.addLine(to: CGPoint(x: width/2, y: 3 * height/4))
path.addLine(to: CGPoint(x: width/2, y: height))
path.addLine(to: CGPoint(x: 0, y: height))
path.closeSubpath()
return path
}
}
struct ContentView: View {
var body: some View {
HStack(spacing: 0) {
Spacer()
Button(action: {}) {
Color.red
.clipShape(ButtonShape())
.overlay(
Text("This is one big button")
)
}
.contentShape(ButtonShape())
.frame(width: 200, height: 200)
Spacer()
}
}
}
此解决方案总体上效果更好,因为没有绘制剪切区域,因此更容易将此按钮放在彩色背景上。