UIPageViewController viewController 转换后消失

UIPageViewController viewController disappears after transition

我在 UINavigationController 中嵌入了 UIPageViewController,而 UINavigationController 又嵌入了 UITabBarController。我只是想使 pageViewController 循环遍历存储在数组中的 viewControllers。但是,每次我尝试移至下一页时,第一个 viewController 会在消失前迅速回到原位。 我将第一个 viewController 设置为红色,将第二个设置为蓝色,奇怪的是在加载它们时我看到了第二个 viewController.

这张 gif 显示了我的意思

我尝试在新项目中以相同的方式设置 pageViewController,一切都按预期工作,所以我看不出问题出在哪里。

import UIKit

final internal class TabBarController: UITabBarController, ApplicationLoginDelegate {

private let newsFeedTableViewController: NewsFeedTableViewController = NewsFeedTableViewController(style: UITableViewStyle.grouped)

private let substitutionPlanTableViewController: SubstitutionPlanTableViewController = SubstitutionPlanTableViewController(style: UITableViewStyle.grouped)

private let loginTableViewController: LoginTableViewController = LoginTableViewController(style: UITableViewStyle.grouped)

private let timeTableViewController: TimeTablePageViewController = TimeTablePageViewController(transitionStyle: UIPageViewControllerTransitionStyle.scroll, navigationOrientation: UIPageViewControllerNavigationOrientation.horizontal, options: nil)

private let moreTableViewController: MoreTableViewController = MoreTableViewController(style: UITableViewStyle.grouped)

//
// MARK: - Override point
//

/**
 Called after the controller's view is loaded into memory.

 This method is called after the view controller has loaded its view hierarchy into memory. This method is called regardless of whether the view hierarchy was loaded from a nib file or created programmatically in the loadView() method. You usually override this method to perform additional initialization on views that were loaded from nib files.
 */
override func viewDidLoad() {

    super.viewDidLoad()

    self.setUpTabBar()

}

/**
 Notifies the view controller that its view is about to be added to a view hierarchy.

 This method is called before the view controller's view is about to be added to a view hierarchy and before any animations are configured for showing the view. You can override this method to perform custom tasks associated with displaying the view. For example, you might use this method to change the orientation or style of the status bar to coordinate with the orientation or style of the view being presented. If you override this method, you must call super at some point in your implementation.

 For more information about the how views are added to view hierarchies by a view controller, and the sequence of messages that occur, see Supporting Accessibility.
 */
override func viewWillAppear(_ animated: Bool) {

    super.viewWillAppear(animated)

    if UIApplication.boolForKey(UserDefaultKey.openSubstitutionPlanOnStartup) == true {
        self.selectedViewController = self.viewControllers?[1]
    }

}

//
// MARK: - Functions
//

private func setUpTabBar() {

    // General
    self.tabBar.tintColor = UIColor.applicationBaseColor
    self.tabBar.unselectedItemTintColor = UIColor.lightGray
    self.tabBar.backgroundColor = UIColor.white

    // Create tab bar items
    let newsFeedTabBarItem: UITabBarItem = UITabBarItem(title: "Aktuelles", image: #imageLiteral(resourceName: "News"), tag: 0)
    let substitutionTabBarItem: UITabBarItem = UITabBarItem(title: "Vertretungen", image: #imageLiteral(resourceName: "SubstitutionPlan"), tag: 1)
    let timeTableTabBarItem: UITabBarItem = UITabBarItem(title: "Stundenplan", image: #imageLiteral(resourceName: "TimeTable"), tag: 2)
    let moreTabBarItem: UITabBarItem = UITabBarItem(title: "Entdecken", image: #imageLiteral(resourceName: "MoreMenu"), tag: 3)

    // Link items and controllers
    self.newsFeedTableViewController.tabBarItem = newsFeedTabBarItem
    self.substitutionPlanTableViewController.tabBarItem = substitutionTabBarItem
    self.loginTableViewController.tabBarItem = substitutionTabBarItem
    self.timeTableViewController.tabBarItem = timeTableTabBarItem
    self.moreTableViewController.tabBarItem = moreTabBarItem

    // Set delegates
    self.loginTableViewController.delegate = self

    // Set tab bar view controllers
    var viewControllers: [UIViewController] = []

    if UIApplication.boolForKey(UserDefaultKey.isUserLoggedIn) == true {
        viewControllers = [newsFeedTableViewController, substitutionPlanTableViewController, timeTableViewController, moreTableViewController]
    } else {
        viewControllers = [newsFeedTableViewController, timeTableViewController, moreTableViewController]
    }

    self.viewControllers = viewControllers.map({ (controller) -> UIViewController in

        controller.navigationItem.largeTitleDisplayMode = .always

        let navigationController = UINavigationController(rootViewController: controller)
        navigationController.navigationBar.prefersLargeTitles = true

        return navigationController
    })

    if UIApplication.boolForKey(UserDefaultKey.isUserLoggedIn) == false {
        self.viewControllers?.insert(self.loginTableViewController, at: 1)
    }

}




}

UITabBarControllerUIPageViewController:

class TimeTablePageViewController: UIPageViewController, UIPageViewControllerDataSource {

private var timeTableViewControllers: [UIViewController]!

override func viewDidLoad() {

    super.viewDidLoad()

    self.dataSource = self

    self.timeTableViewControllers = Array.init(repeating: UIViewController(), count: 2)

    self.timeTableViewControllers[0].view.backgroundColor = .red
    self.timeTableViewControllers[1].view.backgroundColor = .blue

    self.setViewControllers([self.timeTableViewControllers[0]], direction: UIPageViewControllerNavigationDirection.forward, animated: false, completion: nil)

}

func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {

    if let index = self.timeTableViewControllers.index(of: viewController) {
        if viewController == self.timeTableViewControllers.first {
            return self.timeTableViewControllers.last
        } else {
            return self.timeTableViewControllers[index - 1]
        }
    } else {
        return nil
    }

}

func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {

    if let index = self.timeTableViewControllers.index(of: viewController) {
        if viewController == self.timeTableViewControllers.last {
            return self.timeTableViewControllers.first
        } else {
            return self.timeTableViewControllers[index + 1]
        }
    } else {
        return nil
    }

}

}

Array.init(repeating repeatedValue: Array.Element, count: Int)repeatedValue 参数不是闭包。它是将用于填充数组的单个对象。

代码不会为其创建的每个元素调用 UIViewController()。您正在创建一个包含相同 UIViewController 实例两次的数组。一个视图不能有两个 superView,所以当你滚动到第二页时,UIPageViewController 将唯一的 viewController 的视图添加到它的视图中,这意味着它也将从它的视图中删除。

替换

self.timeTableViewControllers = Array.init(repeating: UIViewController(), count: 2)

self.timeTableViewControllers = [UIViewController(), UIViewController()]