添加页面时 UIPageViewController 崩溃
Crash in UIPageViewController when adding pages
在我正在开发的 iOS 11 应用程序中(使用 Swift 4),我需要将页面动态添加到 UIPageViewController
。但是,在某些情况下,我会收到以下崩溃错误 (NSInternalInconsistencyException
):
2017-11-27 14:55:54.787260+0000 MyApp[380:79434] *** Assertion failure in -[UIPageViewController _flushViewController:animated:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3698.21.8/UIPageViewController.m:2124
2017-11-27 14:55:54.791022+0000 MyApp[380:79434] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Don't know about flushed view <UIView: 0x12dd48ac0; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x1c003c280>>'
我是 iOS 开发的新手,如果答案很明显,我很抱歉,但我很难找到崩溃的根本原因。记录的消息也不是很有用...
这是我用来添加页面的代码:
//Inflate the view controller
let viewController = newViewController(param: someParam )
//Add it to the view controllers pool
viewControllersOrdered.insert(viewController, at: getInsertionIndex(param: someOtherParam) )
//Add it to the pageViewController
pageViewController.setViewControllers([viewController], direction: .forward, animated: false, completion: nil)
//Force cache to be cleared
pageViewController.dataSource = nil;
pageViewController.dataSource = self;
getInsertionIndex
功能正常工作,这不是崩溃的根源。
In the iOS 11 app I'm developing (using Swift 4), I need to dynamically add pages to a UIPageViewController.
听起来你的意思是:在用户实际尝试 "turn the page" 之前,你不知道下一个/上一个视图控制器是什么。在那种情况下,滚动的 UIPageViewController 不适合您的体系结构(因为,正如您已经发现的那样,它会预缓存下一页和上一页)。您有两个选择:
使用 page-curl UIPageViewController。它不会预先缓存其页面,因此在用户实际要求翻页之前不会要求您做出决定。
根本不要使用 UIPageViewController;使用分页水平滚动视图并自行管理内容视图。
此外,如果您使用的是 UIPageViewController,则在任何情况下都不应保留子视图控制器的保留列表。这是 UIPageViewController 的工作。您的工作仅仅是提供下一个或上一个视图控制器,您应该按需创建,而不是在其他时间创建,并将其发布到 UIPageViewController 的唯一控件中。
使用 UIPageController
和 scroll
过渡样式的主要无崩溃规则:
1) 在调用setViewControllers
方法之前设置dataSource
2) 使用没有动画的setViewControllers
方法(animated: false
)
3) 将 dataSource
设置为 nil 对于单页模式
4) 不允许循环使用 2 页模式
可以在 my detailed answer
找到稳定子类的完整 Swift
实现
可以在 GitHub project.
找到初始代码和使用示例
在我正在开发的 iOS 11 应用程序中(使用 Swift 4),我需要将页面动态添加到 UIPageViewController
。但是,在某些情况下,我会收到以下崩溃错误 (NSInternalInconsistencyException
):
2017-11-27 14:55:54.787260+0000 MyApp[380:79434] *** Assertion failure in -[UIPageViewController _flushViewController:animated:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3698.21.8/UIPageViewController.m:2124
2017-11-27 14:55:54.791022+0000 MyApp[380:79434] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Don't know about flushed view <UIView: 0x12dd48ac0; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x1c003c280>>'
我是 iOS 开发的新手,如果答案很明显,我很抱歉,但我很难找到崩溃的根本原因。记录的消息也不是很有用...
这是我用来添加页面的代码:
//Inflate the view controller
let viewController = newViewController(param: someParam )
//Add it to the view controllers pool
viewControllersOrdered.insert(viewController, at: getInsertionIndex(param: someOtherParam) )
//Add it to the pageViewController
pageViewController.setViewControllers([viewController], direction: .forward, animated: false, completion: nil)
//Force cache to be cleared
pageViewController.dataSource = nil;
pageViewController.dataSource = self;
getInsertionIndex
功能正常工作,这不是崩溃的根源。
In the iOS 11 app I'm developing (using Swift 4), I need to dynamically add pages to a UIPageViewController.
听起来你的意思是:在用户实际尝试 "turn the page" 之前,你不知道下一个/上一个视图控制器是什么。在那种情况下,滚动的 UIPageViewController 不适合您的体系结构(因为,正如您已经发现的那样,它会预缓存下一页和上一页)。您有两个选择:
使用 page-curl UIPageViewController。它不会预先缓存其页面,因此在用户实际要求翻页之前不会要求您做出决定。
根本不要使用 UIPageViewController;使用分页水平滚动视图并自行管理内容视图。
此外,如果您使用的是 UIPageViewController,则在任何情况下都不应保留子视图控制器的保留列表。这是 UIPageViewController 的工作。您的工作仅仅是提供下一个或上一个视图控制器,您应该按需创建,而不是在其他时间创建,并将其发布到 UIPageViewController 的唯一控件中。
使用 UIPageController
和 scroll
过渡样式的主要无崩溃规则:
1) 在调用setViewControllers
方法之前设置dataSource
2) 使用没有动画的setViewControllers
方法(animated: false
)
3) 将 dataSource
设置为 nil 对于单页模式
4) 不允许循环使用 2 页模式
可以在 my detailed answer
找到稳定子类的完整Swift
实现
可以在 GitHub project.
找到初始代码和使用示例