在 UIViewController 中嵌入 UIPageViewController 停止分页

Embedding a UIPageViewController in a UIViewController stops paging

我正在处理模态呈现的灯箱,但在将 UIPageViewController 嵌入父视图控制器时遇到了问题(以允许 "floating" 未分页的元素)。

以下是包含 UIViewController 的来源。它的 Xib 包含一个 UIButton 和一个 UIView 以及一个名为 workingArea.

的出口

视图数组 (vc) 填充了一个测试 class,将纯色图像放在视图的中心。

@interface LightboxContainerViewController ()

@property (nonatomic) NSArray *vcs;

@end

@implementation LightboxContainerViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.

    UIPageViewController *lb = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];

    lb.dataSource = self;

    self.vcs = @[
                 [[LightboxViewController alloc] initWithNibName:@"LightboxViewController" bundle:nil andImage:[UIImage imageWithColor:[UIColor redColor]]],
                 [[LightboxViewController alloc] initWithNibName:@"LightboxViewController" bundle:nil andImage:[UIImage imageWithColor:[UIColor greenColor]]],
                 [[LightboxViewController alloc] initWithNibName:@"LightboxViewController" bundle:nil andImage:[UIImage imageWithColor:[UIColor blueColor]]]
                 ];

    [lb setViewControllers:@[self.vcs[0]]
                   direction:UIPageViewControllerNavigationDirectionForward
                    animated:NO completion:nil];

    lb.view.frame = self.workingArea.bounds;
    [self.workingArea addSubview:lb.view];
}

-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController
     viewControllerBeforeViewController:(UIViewController *)viewController
{
    NSUInteger currentIndex = [self.vcs indexOfObject:viewController];

    if(currentIndex == 0){
        return nil;
    }
    return [self.vcs objectAtIndex:--currentIndex];
}

-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController
      viewControllerAfterViewController:(UIViewController *)viewController
{
    NSUInteger currentIndex = [self.vcs indexOfObject:viewController];
    if(currentIndex == self.vcs.count - 1){
        return nil;
    }
    // Output selected VC
    return [self.vcs objectAtIndex:++currentIndex];
}

-(NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController
{
    return self.vcs.count;
}

-(NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
{
    return 0;
}

#pragma Modal view management

- (void) presentModal {
    [[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:self animated:YES completion:nil];
    [UIView animateWithDuration:0.3 animations:^{
        [[UIApplication sharedApplication] setStatusBarHidden:YES];
    }];
}

- (void) dismissModal {
    [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
    [UIView animateWithDuration:0.3 animations:^{
        [[UIApplication sharedApplication] setStatusBarHidden:NO];
    }];
}

#pragma mark UI interaction

- (IBAction)closePressed:(id)sender {
    [self dismissModal];
}

#pragma mark UIPageViewControllerDatasource

-(UIViewController *)viewControllerAtIndex:(NSUInteger)index
{
    return self.vcs[index];
}

@end

三个中的第一个 UIViewController 显示正常,滚动指示器中有三个点,但我无法在页面之间滑动。

我设置了断点,viewControllerBeforeViewController/viewControllerAfterViewController 从未被调用,尽管 presentationIndexForPageViewController 被调用。

当数据源方法直接包含在 UIPageViewController 中时,这段代码似乎工作正常,只有当嵌入到父 UIViewController 中时,它才会像这样卡住。

lballoc之后发布。所以它什么也做不了

UIPageViewController *lb = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];

您应该在 .h 或 .m 文件中创建一个 var,例如:

@interface LightboxContainerViewController ()
{
   UIPageViewController *lb
}

@property (nonatomic) NSArray *vcs;

@end

然后

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.



       lb = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
        // .....
    }

为了完整起见,这是我最终做出的更改以及原因(新行标记为 NEW):

- (void)viewDidLoad {

    // ...

     UIPageViewController *lb = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];

    lb.dataSource = self;

    // Populate self.vs here

    // NEW: Added this line to ensure we retain a reference to lb
    [self addChildViewController:lb];

    [lb setViewControllers:@[self.vcs[0]]
                   direction:UIPageViewControllerNavigationDirectionForward
                    animated:NO completion:nil];

    // Set page view controller's view's frame to match host view's frame
    lb.view.frame = self.workingArea.bounds;

    // NEW: Added this line to notify lb of what's happening
    [lb didMoveToParentViewController:self];

    [self.workingArea addSubview:lb.view];
}

这与用于容器视图的模式相同,并确保我们保留对 UIPageViewController 的引用,以便在交互时可以找到委托。

加载后 UIPageViewController 我不需要做任何额外的工作,所以这足以满足我的目的。