SwiftUI: назначение NavigationLink инициализируется всякий раз, когда его родительский элемент перерисовывается

Так что у меня есть ParentView, который имеет NavigationLink, ведущий к UIViewControllerRepresentable-соответствующий PageViewController.

Теперь, когда ParentViewтакже есть подписка на некоторых издателей. Всякий раз, когда этого увольняют, не толькоParentView перерисовать все его содержимое (что должно), он также повторно инициализирует (уже представленный) PageViewController.

Это приводит к заиканию / сбоям, потому что PageViewController уже представляет и использует контроллеры, которые постоянно сбрасываются.

Ниже ParentView а также PageViewController(без Координатора) оба довольно ванильные. Прокомментированная защитная строка - это взлом, который я пытался предотвратить, если он уже отображается. Это помогает, но он все равно заикается при каждом движении.

Итак, возникает вопрос: как мы можем предотвратить обновление представленного ViewController-wrapped-View, когда его представляющее View перерисовывается?

struct ParentView: View {

    @Binding var something: Bool

    var body: some View {
        NavigationLink(destination: PageViewController(controllers: controllers)) {
            Text("Push me")
        }
    }
}
final class PageViewController: UIViewControllerRepresentable {

    var controllers: [UIViewController]
    private var currentPage = 0

    init(controllers: [UIViewController]) {
        self.controllers = controllers
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func makeUIViewController(context: Context) -> UIPageViewController {
        let pageViewController = UIPageViewController(
            transitionStyle: .scroll,
            navigationOrientation: .horizontal)
        pageViewController.dataSource = context.coordinator
        pageViewController.delegate = context.coordinator

        return pageViewController
    }

    func updateUIViewController(_ pageViewController: UIPageViewController, context: Context) {
        // I tried this: guard pageViewController.viewControllers!.isEmpty else { return }
        pageViewController.setViewControllers(
            [controllers[currentPage]], direction: .forward, animated: true)
    }
}

1 ответ

Если ваши контроллеры не меняются после однократного отображения, вы можете просто вызвать:

pageViewController.setViewControllers([controllers[currentPage]], direction: .forward, animated: true)

от makeUIViewController(context:) функция вместо updateUIViewController(:) функция.

Другие вопросы по тегам