我已经阅读了我发现的关于UIPageViewController的每个教程,但是它们只展示了基础知识,我想创建像新的twitter app这样的东西:
UIPageViewController嵌入到导航控制器中,导航栏的标题基于当前页面,并且那些页面点也在那里,用户可以点击当前页面上的项目(项目视图/集合视图中的项目)来查看详细信息。 / p>
我能够想出类似的东西,每个页面都有收藏视图,并且显示某些项目的细节反映在导航栏中,有正确的标题和“<”按钮,但我无法根据当前显示的页面更改标题
请你能用几步/控制器的基本结构来描述我如何做到这一点吗?
答案 0 :(得分: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.h
和ThirdViewController.h
@property (strong, nonatomic) UINavigationItem *navItem;
在上面的第二个和第三个链接中,您将看到Master-Detail应用程序(使用导航控制器)的故事板布局。 UIPageViewControllerDataSource
是DetailViewController
。与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属性来了解要将标题设置为的内容。
希望这有帮助!
答案 1 :(得分:6)
我有一个非常相似的设置并解决了问题。
我的设置是我在UINavigationController中有一个UIPageViewController,因为我想在每个视图控制器之间滑动时导航栏是持久的。我希望UIPageViewController中当前UIViewController的标题成为UINavigationController的标题。
执行此操作的方法是实现UIPageViewControllerDelegate
方法pageViewController didFinishAnimating
,该方法在从UIPageViewController更改到视图控制器后触发。你可能会看到这一点:从这里,设置UIViewPageController的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;
}
}
注意:此委托方法仅触发手势启动的滚动。
答案 2 :(得分: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更容易。
答案 3 :(得分:-1)
先生。伊苏鲁! 我有你的问题...... Micnguyen先生给出的解决方案是确切的解决方案,但是当完成滑动操作时,会调用所提到的委托方法(didFinishAnimating()),因为最初的标题没有显示。
因此要解决这个问题,我们需要在UIPageViewController类的viewDidLoad()方法中设置其初始值,如下所述:
谢谢!