SwiftUI:从子视图中关闭模式

Posted

技术标签:

【中文标题】SwiftUI:从子视图中关闭模式【英文标题】:SwiftUI : Dismiss modal from child view 【发布时间】: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") )

【问题讨论】:

【参考方案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") 
    

【讨论】:

以上是关于SwiftUI:从子视图中关闭模式的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SwiftUI 中随时从子视图作为父视图访问数据?

如何将数据从子视图传递到父视图到 SwiftUI 中的另一个子视图?

关闭自定义模式/覆盖不更新 SwiftUI 中的视图内容

从 NavigationView 呈现的 SwiftUI 关闭模式表(Xcode Beta 5)

SwiftUI 模式表在关闭后重新打开

显示 1 秒后自动关闭模式 - swiftui