SwiftUI:从子视图中关闭模态
SwiftUI : Dismiss modal from child view
我试图在预期操作完成后关闭模态,但我不知道目前如何在 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") })
您可以通过.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 中完成此操作。此模式由 @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") })
您可以通过.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") }
}
}