簡體   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