13

我有一个以编程方式设置的视图控制器,它有一个 child UIPageViewController。这将显示各种其他也以编程方式设置的视图控制器。这些视图控制器的视图已translatesAutoresizingMaskIntoConstraints设置为YES,但页面视图控制器的视图使用约束将自身定位在顶部视图控制器中。

问题是,当用户旋转设备时,页面视图控制器会调整其框架的大小,但其子视图控制器不会。通过didRotateFromInterfaceOrientation,它的框架仍然来自旧的方向。我已经验证在子视图控制器上调用了旋转方法,它们的框架没有改变。

我这样设置页面视图控制器:

self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pageViewController.view.backgroundColor = [UIColor clearColor];
self.pageViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
self.pageViewController.dataSource = self;
self.pageViewController.delegate = self;
[self.pageViewController willMoveToParentViewController:self];
[self.view addSubview:self.pageViewController.view];
[self addChildViewController:self.pageViewController];
[self.pageViewController didMoveToParentViewController:self];

self.currentPageIndex = 0;

self.currentPageController = [self pageForIndex:self.currentPageIndex];
self.currentPageController.delegate = self;
[self.pageViewController setViewControllers:@[self.currentPageController] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:NULL];

我试过打电话setNeedsLayout,但这是一个笨拙的旋转动画,我刷到的下一页也没有正确调整大小。

为什么页面视图控制器不调整其子视图控制器的大小,我该如何让它做到这一点?

谢谢!

4

2 回答 2

6

首先,使用自动布局、以编程方式或 Storyboard 设置所有内容。然后,在父视图控制器中捕捉方向变化并强制 UIPageViewController 的视图重新布局。

这是我的工作代码(iOS 8.0 及更高版本)。childController1设置在 Storyboard 上,所有布局都使用约束,并用[self.storyboard instantiateViewControllerWithIdentifier:@"ChildControllerId"].

- (void)createPageController
{
...
    pageController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
    pageController.dataSource = self;
    [pageController setViewControllers:@[childController1] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
    [self addChildViewController:pageController];
    [self.view addSubview:pageController.view];
    UIView *pageView = pageController.view;
    pageView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[pageView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(pageView)]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[pageView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(pageView)]];
    [pageController didMoveToParentViewController:self];
...
}
- (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    [pageController.view setNeedsLayout];
    [super willTransitionToTraitCollection:newCollection withTransitionCoordinator:coordinator];
}

希望能帮助到你。

于 2015-08-11T17:52:42.683 回答
-2

Adding a controller's view directly into another controller's view and expecting the rotation and life cycle methods to be called isn't the best policy. I kind of feel adding it to the controller hierarchy could work, but I can't comment much on it.

I tested with a tab bar navigator and my UIPageViewController got the events along with the controller that was being shown in the UIPageViewController. I'm guessing that if I push the controller into a UINavigationController I'll get the same result.

I'd recommend you to show your UIPageVIewController in a more standard way than adding it's view to another controller's view.

于 2014-02-02T23:59:05.297 回答