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

时间:2014-02-16 23:13:25

标签: ios objective-c uiview autolayout uipageviewcontroller

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

  

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

我应该如何定位此UILabel以显示在UIPageViewController

2 个答案:

答案 0 :(得分:7)

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

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

我没有创建UIPageViewController的子类,而是创建了一个容器视图控制器(UIViewController的子类),其中UIPageViewController作为子视图控制器。我最初在UIPageViewController中拥有的自定义子视图随后被添加到容器view中。我还将容器作为数据源并委托UIPageViewController

这是一个相关的主题,其中人们得到了相同的断言失败但UITableViewCell"Auto Layout still required after executing -layoutSubviews" with UITableViewCell subclass。大多数建议都不适用于UIPageViewController,但它帮助我弄清楚为什么添加带自动布局的子视图可能会导致问题。

答案 1 :(得分:1)

您还可以继承UIPageViewController并实现此解决方法:

#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