首页 > 解决方案 > SwiftUI 确认按钮 - 在任何其他视图交互时重置状态

问题描述

我想要一个按钮,按下时会变为“确认”。在第二次按下时,它执行操作。到目前为止很简单。

我还希望每当显示按钮的“确认”版本时,与任何其他视图的任何交互都会将按钮重置为其原始状态。这可能是触摸背景、按下另一个按钮、转到另一个选项卡等。

我想要实现的非常简单的例子。

我的尝试是这样的:

struct ContentView: View {
    @State private var confirmShowing = false

    var body: some View {
        ZStack {
            // Tappable background just to remove the confirmation
            Color(.systemBackground)
                .edgesIgnoringSafeArea(.all)
                .onTapGesture {
                    withAnimation {
                        confirmShowing = false
                    }
                }

            VStack {
                // Button which needs confirmation
                Button(action: {
                    if confirmShowing {
                        print("Executing")
                    }
                    withAnimation {
                        confirmShowing.toggle()
                    }
                }) {
                    Text( confirmShowing ? "Confirm" : "Do something" )
                }
                .padding()
                .background( Rectangle().foregroundColor( Color(.secondarySystemBackground) ) )
                .padding()

                // Completely different button which also should first reset confirmation
                Button("Do something else") {
                    withAnimation {
                        confirmShowing = false
                    }
                    // do some other stuff
                }
                    .padding()
                    .background( Rectangle().foregroundColor( Color(.secondarySystemBackground) ) )
                    .padding()
            }
        }
    }
}

它适用于这个非常简单的示例,但它不可扩展。如果我有 50 个视图,我将不得不为每个视图添加一些内容来控制这个按钮。

有没有更好的办法?我很高兴使用 UIViewRepresentable/UIViewControllerRepresentable。

UIKit 一定有这个功能吧?我经常在其他应用程序和 iOS 中看到它。

标签: iosswiftuiuikit

解决方案


我能想到的最好方法是使用枚举来控制按钮的状态。例如。请原谅任何语法错误,我目前没有打开 XCode。

@State var buttonState: ButtonState = .initial

Button(action: {
    switch buttonState {
          case .initial:
              buttonState = .second
          case .second:
               //Perform whatever action after second.
          default:
               buttonState = .initial
     }
}, label: {
    switch buttonState {
        case .initial:
              Text("Some Initial Action")
        case .second:
              Text("Some Second Action")
        default:
              Text("Default Action")
    }
})

然后一旦你有了它,创建一个枚举来处理它。

enum ButtonState {
    case initial, second
}

进一步的用法是简单地添加buttonState = .initial到您想要触发它返回默认值的任何其他按钮。


推荐阅读