如何使用自动布局在UIPageViewController中定位子视图?

我有一个UIPageViewController子类,并在其viewDidLoad我想添加一个UILabel到它的self.view 。 这工作正常,如果我使用框架设置其位置,但如果我尝试使用自动布局来定位它,我得到:

*断言失败 – [_ UIPageViewControllerContentView layoutSublayersOfLayer:],/SourceCache/UIKit_Sim/UIKit-2935.58/UIView.m:8742

我该如何定位这个UILabel在UIPageViewController显示?

这似乎正在发生,因为UIPageViewController的视图(实际上是一个_UIPageViewControllerContentView )不能像预期的那样处理子视图和自动布局(至less在iOS 7中;它在iOS 8中工作正常)。

你可以通过不使用autolayout来解决这个问题,但我想使用自动布局,所以我最终重做了我的视图控制器,以避免向UIPageViewController添加子视图。

我创build了一个UIPageViewController作为子视图控制器的容器视图控制器( UIViewController的子类),而不是UIPageViewController的子类。 我最初在UIPageViewController中的自定义子视图被添加到容器的view 。 我也将容器作为UIPageViewController的数据源和委托。

有一个相关的线程,人们得到相同的断言失败,但与UITableViewCell : “自动布局仍然需要执行-layoutSubviews”与UITableViewCell子类 。 这里的大部分build议不起作用或不适用于UIPageViewController,但是它帮助我弄清楚为什么使用autolayout添加子视图可能会导致问题。

您也可以inheritanceUIPageViewController并实现此解决方法:

 #import <objc/runtime.h> @interface MyPageViewController : UIPageViewController @end @implementation MyPageViewController - (void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; [self applyLayoutSubviewsWorkaroundIfNeeded]; } - (void)applyLayoutSubviewsWorkaroundIfNeeded { // UIPageViewController does not support AutoLayout in iOS7, we get the following runtime error // "_UIPageViewControllerContentView's implementation of -layoutSubviews needs to call super…" // This workaround calls the missing layoutSubviews method of UIView. if ([self iOSVersionIsLowerThan8]) { IMP uiviewLayoutSubviewsImplementation = class_getMethodImplementation([self.view class], @selector(layoutSubviews)); typedef void (*FunctionFromImplementation)(id, SEL); FunctionFromImplementation uiviewLayoutSubviewsFunction = (FunctionFromImplementation)uiviewLayoutSubviewsImplementation; uiviewLayoutSubviewsFunction(self.view, @selector(layoutSubviews)); } } - (BOOL)iOSVersionIsLowerThan8 { // This is just one way of checking if we are on iOS7. // You can use whatever method suits you best return ![self respondsToSelector(popoverPresentationController)]; } @end