当计时器为 运行 时,SwiftUI ActionSheet 不会关闭

SwiftUI ActionSheet does not dismiss when timer is running

我有以下简单的 SwiftUI 设置。 运行 并更新文本的计时器。如果计时器不是 运行(停止或暂停),我可以轻松显示 ActionSheet(通过点击操作)并通过选择“取消”或“操作 1”选项将其关闭。但是如果计时器是 运行,我真的很难通过选择“取消”或“操作 1”选项之一来关闭 ActionSheet。你知道这是怎么回事吗?

我正在使用 Xcode 11.5.

import SwiftUI

struct ContentView: View {
    
    @ObservedObject var stopWatch = StopWatch()
    @State private var showActionSheet: Bool = false
    
    var body: some View {
        VStack {
            Text("\(stopWatch.secondsElapsed)")
            HStack {
                if stopWatch.mode == .stopped {
                    Button(action: { self.stopWatch.start() }) {
                        Text("Start")
                    }
                } else if stopWatch.mode == .paused {
                    Button(action: { self.stopWatch.start() }) {
                        Text("Resume")
                    }
                } else if stopWatch.mode == .running {
                    Button(action: { self.stopWatch.pause() }) {
                        Text("Pause")
                    }
                }
                Button(action: { self.stopWatch.stop() }) {
                    Text("Reset")
                }
            }
            Button(action: { self.showActionSheet = true }) {
                Text("Actions")
            }
            .actionSheet(isPresented: $showActionSheet) {
                ActionSheet(title: Text("Actions"), message: nil, buttons: [.default(Text("Action 1")), .cancel()])
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
import SwiftUI

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

与 Xcode 12 / iOS 14 一起工作正常,但尝试将带有 sheet 的按钮分离到另一个子视图中,以避免在计时器计数器刷新时重新创建它。

测试 Xcode 12 / iOS 14

struct ContentView: View {

    @ObservedObject var stopWatch = StopWatch()
    // @StateObject var stopWatch = StopWatch()       // << used for SwiftUI 2.0
    @State private var showActionSheet: Bool = false

    var body: some View {
        VStack {
            Text("\(stopWatch.secondsElapsed)")
            HStack {
                if stopWatch.mode == .stopped {
                    Button(action: { self.stopWatch.start() }) {
                        Text("Start")
                    }
                } else if stopWatch.mode == .paused {
                    Button(action: { self.stopWatch.start() }) {
                        Text("Resume")
                    }
                } else if stopWatch.mode == .running {
                    Button(action: { self.stopWatch.pause() }) {
                        Text("Pause")
                    }
                }
                Button(action: { self.stopWatch.stop() }) {
                    Text("Reset")
                }
            }
            ActionsSubView(showActionSheet: $showActionSheet)
        }
    }
}

struct ActionsSubView: View {
    @Binding var showActionSheet: Bool
    var body: some View {
        Button(action: { self.showActionSheet = true }) {
            Text("Actions")
        }
        .actionSheet(isPresented: $showActionSheet) {
            ActionSheet(title: Text("Actions"), message: nil, buttons: [.default(Text("Action 1")), .cancel()])
        }
    }
}