SwiftUI 确认按钮 - 在任何其他视图交互时重置状态

Posted

技术标签:

【中文标题】SwiftUI 确认按钮 - 在任何其他视图交互时重置状态【英文标题】:SwiftUI confirmation button - Reset state when any other view interaction 【发布时间】:2021-04-27 20:07:27 【问题描述】:

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

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

我的尝试是这样的:

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 中看到它。

【问题讨论】:

【参考方案1】:

我能想到的最好方法是使用枚举来控制按钮的状态。例如。请原谅任何语法错误,我目前没有打开 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 添加到您想要触发它返回默认值的任何其他按钮。

【讨论】:

我对这种方法的主要问题是我必须将该行添加到可能的许多按钮和其他视图中。在理想的世界中,我会喜欢 onOtherViewTouched 修饰符之类的东西,我可以用它来重置状态。 看看这个“全局点击手势”的解决方案 - ***.com/questions/62400806/… 我认为这应该正是您正在寻找的。请注意,这最终会导致问题。按钮本身也会触发该全局手势,因此您需要确保处理好它。

以上是关于SwiftUI 确认按钮 - 在任何其他视图交互时重置状态的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI List 在任何视图更改时重置滚动

如何修复自定义按钮在 SwiftUI(IOS) 中的交互?

SwiftUI 动画滑入和滑出

在 swiftUI 中是不是可以使用按钮在屏幕上添加新视图?

SwiftUI 的问题:带有按钮的垂直滚动视图

如何在 SwiftUI 视图中包装 UIBarButtonItem?