是否有与 viewWillDisappear(_:) 等效的 SwiftUI 或检测何时将要删除视图?
Is there a SwiftUI equivalent for viewWillDisappear(_:) or detect when a view is about to be removed?
在 SwiftUI 中,我试图找到一种方法来检测 视图即将被删除 仅当使用默认值 navigationBackButton
时。然后执行一些操作。
使用 onDisappear(perform:)
的行为类似于 viewDidDisappear(_:)
,并且该操作在另一个视图出现后执行。
或者,我认为上述问题可以通过检测何时按下 default navigationBarBackButton
来解决。但我没有找到检测的方法。
是否有任何解决方案可以在另一个视图出现之前执行某些操作?
(我已经知道可以通过创建 自定义 导航后退按钮来关闭视图来做到这一点)
这是适合我的方法,它不是纯 SwiftUI,但我认为值得发布
用法:
SomeView()
.onDisappear {
print("x Default disappear")
}
.onWillDisappear { // << order does NOT matter
print(">>> going to disappear")
}
代码:
struct WillDisappearHandler: UIViewControllerRepresentable {
func makeCoordinator() -> WillDisappearHandler.Coordinator {
Coordinator(onWillDisappear: onWillDisappear)
}
let onWillDisappear: () -> Void
func makeUIViewController(context: UIViewControllerRepresentableContext<WillDisappearHandler>) -> UIViewController {
context.coordinator
}
func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<WillDisappearHandler>) {
}
typealias UIViewControllerType = UIViewController
class Coordinator: UIViewController {
let onWillDisappear: () -> Void
init(onWillDisappear: @escaping () -> Void) {
self.onWillDisappear = onWillDisappear
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
onWillDisappear()
}
}
}
struct WillDisappearModifier: ViewModifier {
let callback: () -> Void
func body(content: Content) -> some View {
content
.background(WillDisappearHandler(onWillDisappear: callback))
}
}
extension View {
func onWillDisappear(_ perform: @escaping () -> Void) -> some View {
self.modifier(WillDisappearModifier(callback: perform))
}
}
您可以将子视图的可见性绑定到某个状态,并监视该状态的变化。
当子视图被推送时,onChange
块被调用 show == true
。弹出子视图时,使用 show == false
:
调用相同的块
struct ParentView: View {
@State childViewShown: Bool = false
var body: some View {
NavigationLink(destination: Text("child view"),
isActive: self.$childViewShown) {
Text("show child view")
}
.onChange(of: self.childViewShown) { show in
if show {
// child view is appearing
} else {
// child view is disappearing
}
}
}
}
您可以像这样触发@Environment .scenePhase 的变化:
struct YourView: View {
@Environment(\.scenePhase) var scenePhase
var body: Some View {
VStack {
// Your View code
}
.onChange(of: scenePhase) { phase in
switch phase {
case .active:
print("active")
case .inactive:
print("inactive")
case .background:
print("background")
@unknown default:
print("?")
}
}
}
}
对于要在屏幕上显示的每个对象,您有几个操作
func onDisappear(perform action: (() -> Void)? = nil) -> some View
//Adds an action to perform when this view disappears.
func onAppear(perform action: (() -> Void)? = nil) -> some View
//Adds an action to perform when this view appears.
您可以像示例一样使用(在此示例中它会影响 VStack):
import SwiftUI
struct TestView: View {
@State var textObject: String
var body: some View {
VStack {
Text(textObject)
}
.onAppear {
textObject = "Vertical stack is appeared"
}
.onDisappear {
textObject = ""
}
}
}
struct TestView_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
TestView()
}
}
}
在 SwiftUI 中,我试图找到一种方法来检测 视图即将被删除 仅当使用默认值 navigationBackButton
时。然后执行一些操作。
使用 onDisappear(perform:)
的行为类似于 viewDidDisappear(_:)
,并且该操作在另一个视图出现后执行。
或者,我认为上述问题可以通过检测何时按下 default navigationBarBackButton
来解决。但我没有找到检测的方法。
是否有任何解决方案可以在另一个视图出现之前执行某些操作?
(我已经知道可以通过创建 自定义 导航后退按钮来关闭视图来做到这一点)
这是适合我的方法,它不是纯 SwiftUI,但我认为值得发布
用法:
SomeView()
.onDisappear {
print("x Default disappear")
}
.onWillDisappear { // << order does NOT matter
print(">>> going to disappear")
}
代码:
struct WillDisappearHandler: UIViewControllerRepresentable {
func makeCoordinator() -> WillDisappearHandler.Coordinator {
Coordinator(onWillDisappear: onWillDisappear)
}
let onWillDisappear: () -> Void
func makeUIViewController(context: UIViewControllerRepresentableContext<WillDisappearHandler>) -> UIViewController {
context.coordinator
}
func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<WillDisappearHandler>) {
}
typealias UIViewControllerType = UIViewController
class Coordinator: UIViewController {
let onWillDisappear: () -> Void
init(onWillDisappear: @escaping () -> Void) {
self.onWillDisappear = onWillDisappear
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
onWillDisappear()
}
}
}
struct WillDisappearModifier: ViewModifier {
let callback: () -> Void
func body(content: Content) -> some View {
content
.background(WillDisappearHandler(onWillDisappear: callback))
}
}
extension View {
func onWillDisappear(_ perform: @escaping () -> Void) -> some View {
self.modifier(WillDisappearModifier(callback: perform))
}
}
您可以将子视图的可见性绑定到某个状态,并监视该状态的变化。
当子视图被推送时,onChange
块被调用 show == true
。弹出子视图时,使用 show == false
:
struct ParentView: View {
@State childViewShown: Bool = false
var body: some View {
NavigationLink(destination: Text("child view"),
isActive: self.$childViewShown) {
Text("show child view")
}
.onChange(of: self.childViewShown) { show in
if show {
// child view is appearing
} else {
// child view is disappearing
}
}
}
}
您可以像这样触发@Environment .scenePhase 的变化:
struct YourView: View {
@Environment(\.scenePhase) var scenePhase
var body: Some View {
VStack {
// Your View code
}
.onChange(of: scenePhase) { phase in
switch phase {
case .active:
print("active")
case .inactive:
print("inactive")
case .background:
print("background")
@unknown default:
print("?")
}
}
}
}
对于要在屏幕上显示的每个对象,您有几个操作
func onDisappear(perform action: (() -> Void)? = nil) -> some View
//Adds an action to perform when this view disappears.
func onAppear(perform action: (() -> Void)? = nil) -> some View
//Adds an action to perform when this view appears.
您可以像示例一样使用(在此示例中它会影响 VStack):
import SwiftUI
struct TestView: View {
@State var textObject: String
var body: some View {
VStack {
Text(textObject)
}
.onAppear {
textObject = "Vertical stack is appeared"
}
.onDisappear {
textObject = ""
}
}
}
struct TestView_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
TestView()
}
}
}