SwiftUI:自定义按钮无法识别具有清晰背景和 buttonStyle 的触摸
SwiftUI: Custom button does not recognize touch with clear background and buttonStyle
我在 SwiftUI 中偶然发现 Button
s 与自定义 ButtonStyle
.
相结合的奇怪行为
我的目标是用某种 'push-back animation' 创建自定义 ButtonStyle
。我为此使用了以下设置:
struct CustomButton<Content: View>: View {
private let content: () -> Content
init(content: @escaping () -> Content) {
self.content = content
}
var body: some View {
VStack {
Button(action: { ... }) {
content()
}
.buttonStyle(PushBackButtonStyle(pushBackScale: 0.9))
}
}
}
private struct PushBackButtonStyle: ButtonStyle {
let pushBackScale: CGFloat
func makeBody(configuration: Self.Configuration) -> some View {
configuration
.label
.scaleEffect(configuration.isPressed ? pushBackScale : 1.0)
}
}
// Preview
struct Playground_Previews: PreviewProvider {
static var previews: some View {
CustomButton {
VStack(spacing: 10) {
HStack {
Text("Button Text").background(Color.orange)
}
Divider()
HStack {
Text("Detail Text").background(Color.orange)
}
}
}
.background(Color.red)
}
}
当我现在尝试在 Text
视图之外触摸此按钮时,什么也不会发生。不会显示任何动画,也不会调用操作块。
到目前为止我发现了什么:
- 当您删除
.buttonStyle(...)
时,它会按预期工作(当然没有自定义动画)
- 或者当您在
CustomButton
中的 VStack
上设置 .background(Color.red))
时,它与 .buttonStyle(...)
结合使用时也能正常工作
现在的问题是,是否有人对如何正确解决这个问题或如何修复它有更好的想法?
只需使用 .frame 就可以了。
为了使其易于测试,我将其重写为:
struct CustomButton: View {
var body: some View {
Button(action: { }) {
VStack(spacing: 10) {
HStack {
Text("Button Text").background(Color.orange)
.frame(minWidth: 0, maxWidth: .infinity)
.background(Color.orange)
}
Divider()
HStack {
Text("Detail Text").background(Color.orange)
.frame(minWidth: 0, maxWidth: .infinity)
.background(Color.orange)
}
}
}
.buttonStyle(PushBackButtonStyle(pushBackScale: 0.9))
}
}
private struct PushBackButtonStyle: ButtonStyle {
let pushBackScale: CGFloat
func makeBody(configuration: Self.Configuration) -> some View {
configuration
.label
.scaleEffect(configuration.isPressed ? pushBackScale : 1.0)
}
}
希望能帮到你。 :-)
@用视频编辑。
只需在自定义按钮样式中添加命中测试内容形状,如下所示
测试 Xcode 11.4 / iOS 13.4
private struct PushBackButtonStyle: ButtonStyle {
let pushBackScale: CGFloat
func makeBody(configuration: Self.Configuration) -> some View {
configuration
.label
.contentShape(Rectangle()) // << fix !!
.scaleEffect(configuration.isPressed ? pushBackScale : 1.0)
}
}
我在 SwiftUI 中偶然发现 Button
s 与自定义 ButtonStyle
.
我的目标是用某种 'push-back animation' 创建自定义 ButtonStyle
。我为此使用了以下设置:
struct CustomButton<Content: View>: View {
private let content: () -> Content
init(content: @escaping () -> Content) {
self.content = content
}
var body: some View {
VStack {
Button(action: { ... }) {
content()
}
.buttonStyle(PushBackButtonStyle(pushBackScale: 0.9))
}
}
}
private struct PushBackButtonStyle: ButtonStyle {
let pushBackScale: CGFloat
func makeBody(configuration: Self.Configuration) -> some View {
configuration
.label
.scaleEffect(configuration.isPressed ? pushBackScale : 1.0)
}
}
// Preview
struct Playground_Previews: PreviewProvider {
static var previews: some View {
CustomButton {
VStack(spacing: 10) {
HStack {
Text("Button Text").background(Color.orange)
}
Divider()
HStack {
Text("Detail Text").background(Color.orange)
}
}
}
.background(Color.red)
}
}
当我现在尝试在 Text
视图之外触摸此按钮时,什么也不会发生。不会显示任何动画,也不会调用操作块。
到目前为止我发现了什么:
- 当您删除
.buttonStyle(...)
时,它会按预期工作(当然没有自定义动画) - 或者当您在
CustomButton
中的VStack
上设置.background(Color.red))
时,它与.buttonStyle(...)
结合使用时也能正常工作
现在的问题是,是否有人对如何正确解决这个问题或如何修复它有更好的想法?
只需使用 .frame 就可以了。 为了使其易于测试,我将其重写为:
struct CustomButton: View {
var body: some View {
Button(action: { }) {
VStack(spacing: 10) {
HStack {
Text("Button Text").background(Color.orange)
.frame(minWidth: 0, maxWidth: .infinity)
.background(Color.orange)
}
Divider()
HStack {
Text("Detail Text").background(Color.orange)
.frame(minWidth: 0, maxWidth: .infinity)
.background(Color.orange)
}
}
}
.buttonStyle(PushBackButtonStyle(pushBackScale: 0.9))
}
}
private struct PushBackButtonStyle: ButtonStyle {
let pushBackScale: CGFloat
func makeBody(configuration: Self.Configuration) -> some View {
configuration
.label
.scaleEffect(configuration.isPressed ? pushBackScale : 1.0)
}
}
希望能帮到你。 :-)
@用视频编辑。
只需在自定义按钮样式中添加命中测试内容形状,如下所示
测试 Xcode 11.4 / iOS 13.4
private struct PushBackButtonStyle: ButtonStyle {
let pushBackScale: CGFloat
func makeBody(configuration: Self.Configuration) -> some View {
configuration
.label
.contentShape(Rectangle()) // << fix !!
.scaleEffect(configuration.isPressed ? pushBackScale : 1.0)
}
}