首页 > 解决方案 > SwiftUI:NavigationLink 的目标在其父项被重绘时初始化

问题描述

所以我有一个ParentView,它有一个NavigationLink,导致一个UIViewControllerRepresentable-conforming PageViewController

现在,它ParentView也有一些出版商的订阅。每当那个被触发时,不仅会ParentView重绘它的所有内容(它应该),它还会重新初始化(已经呈现)PageViewController

这会导致卡顿/故障,因为PageViewController它已经在呈现和使用不断被重置的控制器。

下面是ParentViewand PageViewController(没有 Coordinator 的东西),两者都很普通。带注释的警戒线是我试图阻止它更新(如果已经显示)的黑客行为。它有帮助,但每次滑动时它仍然结结巴巴。

所以问题是:当它的呈现视图被重绘时,我们如何防止更新呈现的 ViewController-wrapped-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)
    }
}

标签: swiftuicombinenavigationlink

解决方案


如果您的控制器在显示一次后没有改变,您可以简单地调用:

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

makeUIViewController(context:)函数而不是updateUIViewController(:)函数。


推荐阅读