【问题标题】:SwiftUI : Dismiss modal from child viewSwiftUI:从子视图中关闭模式
【发布时间】:2019-08-21 06:06:10
【问题描述】:

我正在尝试在完成预期操作后关闭模式,但我不知道目前如何在 SwiftUI 中完成此操作。此模式由@State 值更改触发。是否可以通过观察各种通知来更改此值?

期望的操作:Root -> Initial Modal -> Presents Children -> Dismiss modal from any child

以下是我尝试过的

错误:转义闭包会捕获变异的“self”参数

struct AContentView: View {
    @State var pageSaveInProgress: Bool = false

    init(pages: [Page] = []) { 
    // Observe change to notify of completed action
        NotificationCenter.default.publisher(for: .didCompletePageSave).sink { (pageSaveInProgress) in
            self.pageSaveInProgress = false
        }
    }

    var body: some View {
        VStack {
        //ETC
            .sheet(isPresented: $pageSaveInProgress) {
                    ModalWithChildren()
            }
        }
    }
}

ModalWithChildren 测试操作


Button(action: {
    NotificationCenter.default.post(
        name: .didCompletePageSave, object: nil)}, 
        label: { Text("Close") })

【问题讨论】:

    标签: ios swift uiview swiftui combine


    【解决方案1】:

    您可以通过.onReceive(_:perform) 接收消息,该消息可以在任何视图上调用。它注册了一个接收器并将可取消的内容保存在视图中,这使得订阅者的生存时间与视图本身一样长。

    通过它,您可以启动@State 属性更改,因为它从视图主体开始。否则,您将不得不使用ObservableObject,可以从任何地方对其进行更改。

    一个例子:

    struct MyView : View {
        @State private var currentStatusValue = "ok"
        var body: some View {
            Text("Current status: \(currentStatusValue)")
        }
        .onReceive(MyPublisher.currentStatusPublisher) { newStatus in
            self.currentStatusValue = newStatus
        }
    }
    

    一个完整的例子

    import SwiftUI
    import Combine
    
    extension Notification.Name {
        static var didCompletePageSave: Notification.Name {
            return Notification.Name("did complete page save")
        }
    }
    
    struct OnReceiveView: View {
        @State var pageSaveInProgress: Bool = true
    
        var body: some View {
            VStack {
                Text("Usual")
                    .onReceive(NotificationCenter.default.publisher(for: .didCompletePageSave)) {_ in
                        self.pageSaveInProgress = false
                }
                .sheet(isPresented: $pageSaveInProgress) {
                    ModalWithChildren()
                }
            }
        }
    }
    
    struct ModalWithChildren: View {
        @State var presentChildModals: Bool = false
    
        var body: some View {
            Button(action: {
                NotificationCenter.default.post(
                    name: .didCompletePageSave,
                    object: nil
                )
            }) { Text("Send message") }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-24
      • 2021-06-04
      • 1970-01-01
      • 1970-01-01
      • 2021-09-17
      • 2020-05-06
      • 1970-01-01
      相关资源
      最近更新 更多