是否可以在UIPageViewController中以编程方式翻页?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否可以在UIPageViewController中以编程方式翻页?相关的知识,希望对你有一定的参考价值。

是否可以在UIPageViewController中以编程方式翻页?

答案

是的,可以使用以下方法:

- (void)setViewControllers:(NSArray *)viewControllers 
                 direction:(UIPageViewControllerNavigationDirection)direction 
                  animated:(BOOL)animated 
                completion:(void (^)(BOOL finished))completion;`

这与在页面上设置第一个视图控制器的方法相同。类似,您可以使用它来转到其他页面。

想知道为什么viewControllers是一个数组,而不是一个视图控制器?

那是因为页面视图控制器可以有一个“书脊”(就像在iBooks中一样),一次显示2页内容。如果一次显示1页内容,则只传入1元素数组。

Swift中的一个例子:

pageContainer.setViewControllers([displayThisViewController], direction: .Forward, animated: true, completion: nil)
另一答案

我还需要一个按钮在PageViewController上向左导航,这个按钮应该完全按照滑动动作的要求进行操作。

由于我在“pageViewController:viewControllerBeforeViewController”中已经有一些规则用于处理自然滑动导航,我希望按钮能够重复使用所有代码,并且根本无法使用特定索引来覆盖之前的页面答案呢。所以,我不得不采取替代解决方案。

请注意,以下代码适用于页面视图控制器,它是我的自定义ViewController中的属性,其脊椎设置为mid。

这是我为Navigate Left按钮编写的代码:

- (IBAction)btnNavigateLeft_Click:(id)sender {

    // Calling the PageViewController to obtain the current left page
    UIViewController *currentLeftPage = [_pageController.viewControllers objectAtIndex:0];

    // Creating future pages to be displayed
    NSArray *newDisplayedPages = nil;
    UIViewController *newRightPage = nil;
    UIViewController *newLeftPage = nil;

    // Calling the delegate to obtain previous pages
    // My "pageViewController:viewControllerBeforeViewController" method returns nil if there is no such page (first page of the book).
    newRightPage = [self pageViewController:_pageController viewControllerBeforeViewController:currentLeftPage];
    if (newRightPage) {
        newLeftPage = [self pageViewController:_pageController viewControllerBeforeViewController:newRightPage];
    }

    if (newLeftPage) {
        newDisplayedPages = [[NSArray alloc] initWithObjects:newLeftPage, newRightPage, nil];
    }

    // If there are two new pages to display, show them with animation.
    if (newDisplayedPages) {
        [_pageController setViewControllers:newDisplayedPages direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:nil];
    }
}

你可以做一些非常相似的事情,从这里做一个正确的导航按钮。

另一答案

对于单页,我刚刚编辑了@Jack Humphries的答案

-(void)viewDidLoad
{
  counter = 0;
}
-(IBAction)buttonClick:(id)sender
{
  counter++;
  DataViewController *secondVC = [self.modelController viewControllerAtIndex:counter storyboard:self.storyboard];
  NSArray *viewControllers = nil;          
  viewControllers = [NSArray arrayWithObjects:secondVC, nil];          
  [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
}
另一答案

如果PAGE CONTROL指示当前页面是O &&您希望页面通过滚动导航,也可以通过单击Page ViewController中的自定义按钮,下面可能会有所帮助。

//Set Delegate & Data Source for PageView controller [Say in View Did Load]
   self.pageViewController.dataSource = self;
   self.pageViewController.delegate = self;

// Delegates called viewControllerBeforeViewController when User Scroll to previous page 

 - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController{

    [_nextBtn setTitle:@"Next" forState:UIControlStateNormal];

    NSUInteger index = ((PageContentViewController*) viewController).pageIndex;

    if (index == NSNotFound){
        return nil;
    }else if (index > 0){
        index--;
    }else{
        return nil;
    }        
    return [self viewControllerAtIndex:index];        
}

//当用户滚动到下一页时,委托调用viewControllerAfterViewController

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController{

    NSUInteger index = ((PageContentViewController*) viewController).pageIndex;

if (index == NSNotFound){
    return nil;
}else if (index < 3){
    index++;
}else{
    return nil;
}
return [self viewControllerAtIndex:index];}

//Delegate called while transition of pages. The need to apply logic in this delegate is to maintain the index of current page.

 - (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers{ 

buttonIndex = (int)((PageContentViewController*) pendingViewControllers.firstObject).pageIndex;

}

-(void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed{    
if (buttonIndex == 0){
    _backButton.hidden = true;
}else if (buttonIndex == [self.pageImages count] - 1){
    _backButton.hidden = false;
    [_nextBtn setTitle:@"Begin" forState:UIControlStateNormal];
}else{
    _backButton.hidden = false;
}

}

//自定义按钮(上一个和下一个)逻辑

-(void)backBtnClicked:(id)sender{
    if (buttonIndex > 0){
buttonIndex -= 1;
    }
    if (buttonIndex < 1) {
        _backButton.hidden = YES;
    }
    if (buttonIndex >=0) {
         [_nextBtn setTitle:@"Next" forState:UIControlStateNormal];
        PageContentViewController *startingViewController = [self viewControllerAtIndex:buttonIndex];
        NSArray *viewControllers = @[startingViewController];
        [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
    }

}

-(void)nextBtnClicked:(id)sender{
if (buttonIndex < 3){
buttonIndex += 1;
}
if(buttonIndex == _pageImages.count){
   //Navigate Outside Pageview controller        
}else{        
    if (buttonIndex ==3) {

        [_nextBtn setTitle:@"Begin" forState:UIControlStateNormal];
    }
    _backButton.hidden = NO;

    PageContentViewController *startingViewController = [self viewControllerAtIndex:buttonIndex];
    NSArray *viewControllers = @[startingViewController];
    [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
}

}

//BUTTON INDEX & MAX COUNT
-(NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController{
    return [self.pageImages count];}

-(NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController{
    return  buttonIndex;}
另一答案
- (void)moveToPage {

    NSUInteger pageIndex = ((ContentViewController *) [self.pageViewController.viewControllers objectAtIndex:0]).pageIndex;

    pageIndex++;

    ContentViewController *viewController = [self viewControllerAtIndex:pageIndex];

if (viewController == nil) {
        return;
    }
    [self.pageViewController setViewControllers:@[viewController] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];

}

//现在调用此方法

[self moveToPage];

我希望它有效:)

另一答案

正如@samwize指出的那样,分页的方式是使用

setViewControllers:array

这就是我做的方式:我将数据源和委托分开。您可以调用此方法并仅更改“下一个”视图。以前,您必须应用分页规则。也就是说,你必须检查方向和下一个控制器。如果将该方法与自定义数据源一起使用,则显示的控制器数组将不会更改(因为您将在NSObject子类上使用自定义数组)。

使用您自己的数据源,该方法只是设置一个新视图(具有特定方向)。因为您仍然可以控制正常滑动时显示的页面。

另一答案

我从昨天开始研究它,我终于做到了。我完全不能使用标准模板,因为我有三个不同的viewControllers作为子视图:

1 - rootViewController;
2 - model;
3 - viewControllers
3.1 - VC1;
3.2 - VC2;
3.3 - VC3.
Note: all of VCs has Storyboard ID.

我只在第一个VC中需要一个触发按钮,所以我为pageViewController和model添加了一个属性:

#import <UIKi

以上是关于是否可以在UIPageViewController中以编程方式翻页?的主要内容,如果未能解决你的问题,请参考以下文章

如何判断UIPageViewController页面是否转动是由于滑动/平移或点击

禁用 UIPageViewController 反弹

UIPageViewController 页面控件背景颜色

UIPageViewController 必须全屏吗?

UIPageViewController:从右到左的语言反转 .scroll 动画方向

在 UIPageViewController 的 UIPageControl 中增加指示器的大小