NavigationController中的UIPageViewController

问题描述 投票:18回答:4

我已经阅读了我发现的关于UIPageViewController的每个教程,但是它们只展示了基础知识,我想创建类似新的twitter应用程序的东西:

UIPageViewController嵌入到导航控制器中,导航栏的标题基于当前页面,并且那些页面点也在那里,用户可以点击当前页面上的项目(项目视图/集合视图中的项目)来查看详细信息。

我能够得到类似的东西,每个页面都有收集视图,并显示某些项目的细节反映在导航栏中,有正确的标题和“<”按钮,但我无法根据当前更改标题显示的页面

拜托,您能用几步/控制器的基本结构来描述我如何做到这一点吗?

ios7 uinavigationcontroller uipageviewcontroller
4个回答
15
投票

不知道你是否还在努力,但无论如何都要去。要设置UIPageViewController,您可以使用本教程和下面两个问题。

http://www.appcoda.com/uipageviewcontroller-storyboard-tutorial/

How to implement UIPageViewController that utilizes multiple ViewControllers

How to add UIBarButtonItem to NavigationBar while using UIPageViewController

最后一个链接专门用于根据您正在查看的内容设置navigationBar的内容。

关键是在UIPageViewController内容视图控制器的.h文件中创建UINavigationItem属性,这意味着显示正在显示的内容的那些/一个。

从我在FirstViewController.h SecondViewController.hThirdViewController.h的代码

@property (strong, nonatomic) UINavigationItem *navItem;  

在上面的第二个和第三个链接中,您将看到Master-Detail应用程序(使用导航控制器)的故事板布局。 UIPageViewControllerDataSourceDetailViewController。与pageViewController相关的三个页面是我的内容视图控制器。

在DetailViewController.m中,您必须在某处实例化contentViewControllers。此时,您将DetailViewControllers navigationItem id传递给内容视图控制器。这是我使用UIPageViewController的委托方法实例化我的内容视图控制器的方法。

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

    NSString * ident = viewController.restorationIdentifier;
    NSUInteger index = [_vc indexOfObject:ident];

    if ((index == 0) || (index == NSNotFound)) {
        return nil;
    }

    index--;

    if (index == 0) {
        return [self controllerAtIndex:index];
    }else if (index == 1){
        return [self secondControllerAtIndex:index];
    }else if (index == 2){
        return [self thirdControllerAtIndex:index];
    }else{
        return nil;
    }
}

委托方法调用下面的方法。它几乎直接来自教程链接,只需进行一些修改。

-(FirstController *)controllerAtIndex:(NSUInteger)index
{
    FirstController *fvc = [self.storyboard instantiateViewControllerWithIdentifier:@"FirstPageController"];
    fvc.imageFile = self.pageImages[index];
    fvc.titleText = self.pageTitles[index];
    fvc.pageIndex = index;
    fvc.navItem = self.navigationItem;
    return fvc;
}

请注意,属性将传递到视图控制器,包括self.navigationItem。传入它可确保您可以更改navigationBar项目。

然后在内容视图控制器的viewDidAppear方法中,您可以像这样在导航栏上设置标题。

navItem.navigationItem.title = @"Whatever you want the title to be";

使用viewDidAppear很重要,因为每次屏幕出现时都不会调用viewDidLoad。我相信UIPageViewController在您查看之前缓存页面之前和页面,这使得系统不必每次导航时都必须加载页面。

如果您对所有页面使用单个视图控制器(如教程),则必须使用index属性来了解要将标题设置为的内容。

希望这可以帮助!


6
投票

我有一个非常相似的设置,并解决了这个问题。

我的设置是我在UINavigationController中有一个UIPageViewController,因为我想在每个视图控制器之间刷卡时导航栏是持久的。我希望UIPageViewController中当前UIViewController的标题成为UINavigationController的标题。

这样做的方法是实现UIPageViewControllerDelegate方法pageViewController didFinishAnimating,它在从UIPageViewController更改到视图控制器后触发。您可以看到这种情况:从这里开始,设置UIVavPageController的navigationItem.title属性,UINavigationController用它来设置自己的标题,以及当前视图控制器标题的属性。

例:

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
    if(finished && completed)
    {
        NSString *titleOfIncomingViewController = [[pageViewController.viewControllers firstObject] title];
        pageViewController.navigationItem.title = titleOfIncomingViewController;
    } 
}

注意:此委托方法仅触发手势启动的滚动。


0
投票

我也有这个问题,但最后做了一些不同的事情,因为我正在使用Swift,所以我想我会在这里分享。

我最终在我的导航控制器的容器视图中嵌入了一个UIPageViewController。在页面滑动,我使用pageViewController(_:didFinishAnimating:previousViewControllers:transitionCompleted :),我的PageViewController作为UIPageViewDelegate。从那里我创建了一个协议,用于将显示的VC数据发送到父VC,并使用self.title = "My Title"更改标题。

我没有让父VC成为UIPageViewDelegate,因为我发现从PageViewController访问显示的VC比从let childVC = pageViewController.viewControllers![0] as! DetailViewController访问父VC更容易。


-1
投票

伊苏鲁先生!我得到了你的问题...... Micnguyen先生给出的解决方案是确切的解决方案,但是当完成滑动操作时会调用所提到的委托方法(didFinishAnimating()),因为最初的标题没有显示。

因此,要解决该问题,我们需要在UIPageViewController类的viewDidLoad()方法中设置其初始值,如下所述:

  • (void)viewDidLoad(){self.navigationitem.title = arrayname [0]; }

谢谢 !

© www.soinside.com 2019 - 2024. All rights reserved.