计时器更新视图时,SwiftUI NavBar按钮不起作用

时间:2020-10-30 04:40:00

标签: swiftui

似乎在计时器更新视图时触发NavBar按钮存在问题。 在下面的示例中,“关闭”按钮有效,但“导航栏”按钮“取消”无效。 知道为什么吗?或如何解决

struct ContentView: View {
    @State var isPresented = false
    var body: some View {
        Button(action: {
            isPresented = true
        }, label: {
            Text("Button")
        })
        .sheet(isPresented: $isPresented, content: {
            ModalView()
        })
    }
}

class Model: ObservableObject {
    private var monitorTimer: Timer?
   
    @Published var someThing: Bool = false
    
    init() {
        startMonitoring()
    }
    
    func startMonitoring() {
        monitorTimer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true, block: { _ in
            self.someThing.toggle()
        })
    }
}

struct ModalView: View {
    @Environment(\.presentationMode) private var presentationMode
    @StateObject var model = Model()
    
    var body: some View {
        NavigationView {
            VStack{
                if model.someThing {
                    Text("True")
                } else {
                    Text("False")
                }
                
                Button(action: {
                    presentationMode.wrappedValue.dismiss()
                }, label: {
                    Text("Close")
                })
            }
            .navigationBarTitle("Modal")
            .navigationBarItems(
                leading:
                    Button("Cancel") {
                        presentationMode.wrappedValue.dismiss()
                    })
        }
    }
}


1 个答案:

答案 0 :(得分:0)

这是经过测试的解决方法(Xcode 12 / iOS 14)。解决方案是将子视图分开,以避免全局刷新,如下所示

注意:顺便说一句-不要忘了在关闭模式下停止计时器,因为状态对象仍然有效,所以现在您的计时器即使在工作表关闭后也可以运行

struct ModalView: View {
    @StateObject var model = Model()
    
    var body: some View {
        InternalModal().environmentObject(model)
    }
}

struct InternalModal: View {
    @Environment(\.presentationMode) private var presentationMode
    var body: some View {
        NavigationView {
            VStack{
                UpdatingView()

                Button(action: {
                    presentationMode.wrappedValue.dismiss()
                }, label: {
                    Text("Close")
                })
            }
            .navigationBarTitle("Modal")
            .navigationBarItems(
                leading:
                    Button(action: {
                        presentationMode.wrappedValue.dismiss()
                    }) {
                        Text("Cancel")
                    })
        }
    }
}

struct UpdatingView: View {
    @EnvironmentObject var model: Model
    var body: some View {
        if model.someThing {
            Text("True")
        } else {
            Text("False")
        }
    }
}