Есть ли SwiftUI-эквивалент для viewWillDisappear (_ :) или определить, когда представление будет удалено? - PullRequest
3 голосов
/ 15 января 2020

В SwiftUI я пытаюсь найти способ обнаружить, что представление собирается быть удаленным только при использовании значения по умолчанию navigationBackButton. Затем выполните какое-либо действие.

Использование onDisappear(perform:) действует как viewDidDisappear(_:), и действие выполняется после появления другого представления.

Или, я думал, что вышеуказанную проблему можно решить, обнаружив, когда по умолчанию navigationBarBackButton нажата. Но я не нашел способа обнаружить это.

Есть ли какое-либо решение для выполнения какого-либо действия до появления другого представления?

(я уже знаю, что это можно сделать, создав пользовательская кнопка перехода назад, чтобы закрыть вид)

1 Ответ

4 голосов
/ 15 января 2020

Вот подход, который работает для меня, это не чистый 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))
    }
}
...