繁体   English   中英

计时器运行时,SwiftUI 警报不会关闭

[英]SwiftUI Alert does not dismiss when timer is running

半相关问题: SwiftUI ActionSheet 在计时器运行时不会关闭

我目前在我正在进行的项目中遇到警报问题。 当有计时器在后台运行时,显示的警报不会解除。 大多数情况下,它需要点击几下关闭按钮才能消失。 我在示例项目中以尽可能少的开销重新创建了这个问题。

我的主要项目在尝试在不同视图上显示警报时出现此问题,但我无法在示例项目中重现该问题。 通过在计时器运行的同一视图上切换警报,可以可靠地复制该问题。 我还通过从文本字段中删除绑定来阻止文本字段视图更新来进行测试。 第一次单击时警报仍然无法解除。 我不确定是否有办法解决这个问题,我正在寻找任何可能的建议。

Xcode 13.0/iOS 15.0 和 iOS 14.0 中也出现

Timerview.swift

struct TimerView: View {
    @ObservedObject var stopwatch = Stopwatch()
    @State var isAlertPresented:Bool = false
    var body: some View {
        VStack{
            Text(String(format: "%.1f", stopwatch.secondsElapsed))
                 .font(.system(size: 70.0))
                 .minimumScaleFactor(0.1)
                 .lineLimit(1)
            Button(action:{
                stopwatch.actionStartStop()
            }){
                Text("Toggle Timer")
            }
            
            Button(action:{
                isAlertPresented.toggle()
            }){
                Text("Toggle Alert")
            }
        }
        .alert(isPresented: $isAlertPresented){
            Alert(title:Text("Error"),message:Text("I  am presented"))
        }  
    }
}

秒表.swift

class Stopwatch: ObservableObject{
    @Published var secondsElapsed: TimeInterval = 0.0
        @Published var mode: stopWatchMode = .stopped
        
    
    func actionStartStop(){
        if mode == .stopped{
            start()
        }else{
            stop()
        }
    }
    
    var timer = Timer()
    func start() {
        secondsElapsed = 0.0
        mode = .running
        timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in
            self.secondsElapsed += 0.1
        }
    }
    
    func stop() {
        timer.invalidate()
        mode = .stopped
    }
    
    enum stopWatchMode {
        case running
        case stopped
    }
}

编辑:将按钮移动到自定义视图解决了最初的问题,但是当按钮需要与 Observable 对象交互时是否有解决方案?

         Button(action:{
             do{
                 try stopwatch.actionDoThis()
             }catch{
                 isAlertPresented = true
             }
         }){
          Text("Toggle Alert")
         }.alert(isPresented: $isAlertPresented){
          Alert(title:Text("Error"),message:Text("I  am presented"))

每次计时器运行时 UI 都会重新创建,因为“secondsElapsed”是一个可观察对象。 SwiftUI 将自动监视“secondsElapsed”中的变化,并重新调用视图的 body 属性。 为了避免这种情况,我们需要将按钮和警报分开到另一个视图,如下所示。

struct TimerView: View {
   @ObservedObject var stopwatch = Stopwatch()
   @State var isAlertPresented:Bool = false
   var body: some View {
     VStack{
        Text(String(format: "%.1f", stopwatch.secondsElapsed))
            .font(.system(size: 70.0))
            .minimumScaleFactor(0.1)
            .lineLimit(1)
        Button(action:{
            stopwatch.actionStartStop()
        }){
            Text("Toggle Timer")
        }
        CustomAlertView(isAlertPresented: $isAlertPresented)
    }
  }
}

struct CustomAlertView: View {
  @Binding var isAlertPresented: Bool
    var body: some View {
       Button(action:{
        isAlertPresented.toggle()
       }){
        Text("Toggle Alert")
       }.alert(isPresented: $isAlertPresented){
        Alert(title:Text("Error"),message:Text("I  am presented"))
    }
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM