SwiftUI:从子视图中关闭模态

时间:2019-08-21 06:06:10

标签: swiftui combine

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

所需动作:根->初始模态->提出孩子->从任何孩子身上消除模态

下面是我尝试过的

错误:转义转义符捕获了变异的'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")
                    })

1 个答案:

答案 0 :(得分:4)

您可以通过.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") }
    }
}