SwiftUI:是否有一种方法将按钮放在另一个按钮内部?

11

我正在尝试使用SwiftUI在另一个按钮内插入一个按钮。然而,如果我按下该按钮,它也会动画显示外部按钮被按下,即使它不运行操作闭包。是否有一种方法可以防止这种情况,例如使用自定义ButtonStyle?

它看起来像这样:

Button

当内部按钮被按下时,它看起来像这样:

Pressed Button

以下是我的代码:

var body: some View {
    Button(action: {
        print("outer button pressed")
    }) {
        HStack {
            Text("Button")
            Spacer()
            Button(action: {
                print("inner button pressed")
            }) {
                Circle()
                    .foregroundColor(Color.accentColor.opacity(0.2))
                    .frame(width: 28.0, height: 28.0)
                    .overlay(Image(systemName: "ellipsis"))
            }
        }
        .padding()
        .accentColor(.white)
        .background(Color.accentColor)
        .clipShape(RoundedRectangle(cornerRadius: 14.0, style: .continuous))
    }
    .frame(maxWidth: 200.0)
    .padding()
}

1
重新考虑使用轻拍手势来代替内部按钮的圆形设计。 - Asperi
1
@Asperi 感谢您的建议。我考虑过使用onTapGesture,但使用一个不响应点击的按钮会感觉很奇怪。我也尝试使用onLongPressGesture,但效果并不是很好。 - 1-877-547-7272
2个回答

5

使用两个不同的按钮放在一个ZStack中如何?

var body: some View {
    
    ZStack(alignment: .trailing) {
        
        Button(action: {
            print("outer button pressed")
        }) {
            HStack {
                Text("Button")
                Spacer()
            }
            .padding()
            .accentColor(.white)
            .background(Color.accentColor)
            .clipShape(RoundedRectangle(cornerRadius: 14.0, style: .continuous))
        }
        .frame(maxWidth: 200.0)
        .padding()

        Button(action: {
            print("inner button pressed")
        }) {
            Circle()
                .foregroundColor(Color.accentColor.opacity(0.2))
                .frame(width: 28.0, height: 28.0)
                .overlay(Image(systemName: "ellipsis"))
            .padding()
            .accentColor(.white)
            .clipShape(RoundedRectangle(cornerRadius: 14.0, style: .continuous))
        }
        .padding()

    }
}

1
如果有人需要在Apple Watch上重复此操作,您应该在ZStack中的每个按钮上添加.buttonStyle(.plain) - Suprafen

0

可能会有更优雅的解决方案,但以下代码应该能够提供您想要的行为:

struct ContentView: View {
    @State private var innerButtonDidTap = false
    @State private var outerButtonDidTap = false
   
    var body: some View {
        HStack {
            Text("Button")

            Spacer()

            Circle()
                .onTapGesture {
                    print("inner button tapped")
                    innerButtonDidTap.toggle()
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
                        innerButtonDidTap.toggle()
                    }
                }
                .foregroundColor(Color.accentColor.opacity(innerButtonDidTap ? 1.0 : 0.2))
                .frame(width: 28.0, height: 28.0)
                .overlay(Image(systemName: "ellipsis"))
            
        }
        .contentShape(Rectangle())
        .onTapGesture {
            print("outer button tapped")
            outerButtonDidTap.toggle()
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
                outerButtonDidTap.toggle()
            }
        }
        .frame(maxWidth: 200)
        .padding()
        .accentColor(.white)
        .foregroundColor(.white)
        .background(Color.accentColor.opacity(outerButtonDidTap ? 0.2 : 1))
        .animation(Animation.linear(duration: 0.1))
        .clipShape(RoundedRectangle(cornerRadius: 14.0, style: .continuous))
    }
}

所以,我不使用两个按钮,而是结合两个onTapGesture修饰符使用HStackCircle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接