ios - 计时器运行时,SwiftUI 警报不会关闭
问题描述
半相关问题: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"))
}
}
}
推荐阅读
- amazon-web-services - 以编程方式将多个事件通知添加到 s3 存储桶
- amazon-web-services - 如何在 ASP.NET 中获取上传到 S3 的图像的缩略图?
- python - 我需要在@app.route() 中使用 methods=['GET', 'POST'] 吗?
- python - Django 视图流 - 创建->待处理->发布->编辑->待处理->发布
- ios - 导航栏的 .isTranslucent 颜色的 rgb 等效颜色是什么?
- go - gob 编码崩溃
- r - R vlookup 结合 if...and
- javascript - 为什么当我使用键盘键导航时滚动不起作用
- mysql - 从第二个表中获取 3 列和多条记录的总和
- javascript - JavaScript:解决算法问题