基于分页导航实现

在iOS 5之后,可以使用分页控制器(UIPageViewController)构建类似于电子书效果的应用,我们称为基于分页的应用。一个分页应用有很多相关的视图控制器

分页控制器(PageViewController)需要放置在一个父视图控制器中,在分页控制器下面还要有子视图控制器,每个子视图控制器对应图中的一个页面。

在基于分页导航实现的应用中需要的类和协议:UIPageViewControllerDataSource协议和 UIPageViewControllerDelegate协议和UIPageViewController 类,UIPageViewController没有对应的视图类。

UIPageViewControllerDelegate委托协议中,最重要的方法为 pageViewController:spineLocationForInterfaceOrientation:,它根据屏幕旋转方向设置书脊位置 (Spine Location)和初始化首页。

UIPageViewController中有两个常用的属性:双面显示(doubleSided)和书脊位置(spineLocation)。

1.双面显示,是在页面翻起的时候,偶数页面会在背面显示。图为doubleSided设置为YES情况,图6-14中图为 doubleSided设置为NO(单面显示),单面显示在页面翻起的时候,能够看到页面的背面,背面的内容是当前页面透过去的,与当前内容是相反的镜 像。

2.书脊位置。书脊位置也是很重要的属性,但是它的spineLocation 属性是只读的,要设置它,需要通过 UIPageViewControllerDelegate委托协议中的 pageViewController:spineLocationForInterfaceOrientation:方法。书脊位置由枚举 UIPageViewControllerSpineLocation定义,该枚举类型下的成员变量如下所示。

     

下面我们使用页面导航实现城市信息这个应用。使用Single View Application模板创建一个名为 PageNavigation的工程。

可以从PageControlNavigation工程中复制过来,方法是在打开MainStoryboard.storyboard选中3个视图 控制器,按下Command+C组合键拷贝,再到PageNavigation中打开MainStoryboard.storyboard,按下 Command+V组合键粘贴,就可以了。

这样UI设计工作就结束了,下面的工作都是由代码完成的。我们先看看ViewController.h的代码:

  1. #import <UIKit/UIKit.h>
  2. @interface ViewController : UIViewController <UIPageViewControllerDataSource,UIPageViewControllerDelegate>
  3. {
  4. //当前页面的索引
  5. int pageIndex;
  6. }
  7. @property (strong, nonatomic) UIPageViewController *pageViewController;
  8. @end

在上述代码中,ViewController实现了UIPageViewControllerDataSource和 UIPageViewControllerDelegate协议。成员变量pageIndex保存了当前页面的索 引,pageViewController属性保存了UIPageViewController实例。

下面我们看看程序代码ViewController.m的viewDidLoad方法:

  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. self.view.frame = CGRectMake(0.0f, 0.0f, 320.0f, 440.0f);
  5. self.pageViewController = [[UIPageViewController alloc]
  6. initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl
  7. navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
  8. self.pageViewController.delegate = self;
  9. self.pageViewController.dataSource = self;
  10. UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
  11. UIViewController* page1ViewController = [mainStoryboard instantiateViewControllerWithIdentifier:@"page1"];
  12. //第一个视图,最为PageViewController首页
  13. NSArray *viewControllers = @[page1ViewController];
  14. [self.pageViewController setViewControllers:viewControllers
  15. direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
  16. [self addChildViewController:self.pageViewController];
  17. [self.view addSubview:self.pageViewController.view];
  18. pageIndex = 0;
  19. }

在上述代码中,initWithTransitionStyle:navigationOrientation:options:构造方法用于创建 UIPageViewController实例,initWithTransitionStyle用于设定页面翻转的样式。 UIPageViewControllerTransitionStyle枚举类型定义了如下两个翻转样式。

UIPageViewControllerTransitionStylePageCurl:翻书效果样式。

UIPageViewControllerTransitionStyleScroll:滑屏效果样式。

navigationOrientation设定了翻页方向,UIPageViewControllerNavigationDirection枚举类型定义了以下两种翻页方式。

UIPageViewControllerNavigationDirectionForward:从左往右(或从下往上);

UIPageViewControllerNavigationDirectionReverse:从右向左(或从上往下)。

代码NSArray *viewControllers = @[page1ViewController]相当于NSArray *viewControllers = [NSArray arrayWithObject: page1ViewController , nil]。

在UIPageViewController 中,setViewControllers:direction:animated:completion:方法用于设定首页中显示的视图。首页中显示几 个视图与书脊类型有关,如果是UIPageViewControllerSpineLocationMin或 UIPageViewControllerSpineLocationMax,首页中显示一个视图;如果是 UIPageViewControllerSpineLocationMid,首页中显示两个视图。

[self addChildViewController:self.pageViewController]语句是将PageViewController添加到父视图控制器中去。

我们再看看ViewController.m中有关数据源UIPageViewControllerDataSource协议实现方法的代码:

  1. - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
  2. viewControllerBeforeViewController:(UIViewController *)viewController
  3. {
  4. pageIndex–;
  5. if (pageIndex < 0){
  6. pageIndex = 0;
  7. return nil;
  8. }
  9. UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
  10. NSString *pageId = [NSString stringWithFormat:@"page%i",pageIndex+1];
  11. UIViewController* pvController = [mainStoryboard instantiateViewControllerWithIdentifier:pageId];
  12. return pvController;
  13. }
  14. - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
  15. viewControllerAfterViewController:(UIViewController *)viewController
  16. {
  17. pageIndex++;
  18. if (pageIndex > 2){
  19. pageIndex = 2;
  20. return nil;
  21. }
  22. UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
  23. NSString *pageId = [NSString stringWithFormat:@"page%i",pageIndex+1];
  24. UIViewController* pvController = [mainStoryboard instantiateViewControllerWithIdentifier:pageId];
  25. return pvController;
  26. }
  27. 在ViewController.m中,有关委托协议UIPageViewControllerDelegate实现方法的代码如下:
  28. - (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController
  29. spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation
  30. {
  31. self.pageViewController.doubleSided = NO;
  32. return UIPageViewControllerSpineLocationMin;
  33. }
  34. 由于spineLocation属性是只读的,所以只能在这个方法中设置书脊位置,该方法可以根据屏幕旋转方向的不同来动态设定书脊的位置,实现代码可以参考下面的代码:
  35. - (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController
  36. spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation
  37. {
  38. UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
  39. UIViewController* page1ViewController = [mainStoryboard instantiateViewControllerWithIdentifier:@"page1"];
  40. UIViewController* page2ViewController = [mainStoryboard instantiateViewControllerWithIdentifier:@"page2"];
  41. if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
  42. {
  43. //取出第一个视图控制器,最为PageViewController首页
  44. NSArray *viewControllers = @[page1ViewController, page2ViewController];
  45. [self.pageViewController setViewControllers:viewControllers
  46. direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
  47. self.pageViewController.doubleSided = NO;
  48. return UIPageViewControllerSpineLocationMid;
  49. }
  50. //取出第一个视图控制器,最为PageViewController首页
  51. NSArray *viewControllers = @[page1ViewController];
  52. [self.pageViewController setViewControllers:viewControllers
  53. direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
  54. self.pageViewController.doubleSided = NO;
  55. return UIPageViewControllerSpineLocationMin;
  56. }

这只是一个基本的实现,要根据具体的应用具体再定。用平铺导航实现时,UIPageViewController往往不需要实现屏幕旋转的支持,而且书脊的位置也不会设置在中间。

代码编写完毕看效果。

iOS开发那些事-平铺导航-基于Page的导航及案例实现相关推荐

  1. iOS开发那些事-平铺导航–基于分屏导航及案例实现

    平铺导航模式是非常重要的导航模式.一般用于简单的扁平化信息浏览或任务.扁平化信息是指这些信息之间没有从属的层次关系,如中国的城市中北京.上 海和哈尔滨之间是扁平化信息,而哈尔滨市与黑龙江省之间的关系是 ...

  2. iOS开发那些事-故事板实现标签导航

    故事板实现标签导航 用故事板技术实现标签导航模式. 使用"Tabbed Application"模版,创建一个名为 "TabNavigationStoryborad&qu ...

  3. iOS开发那些事--创建基于故事板的iOS 6的HelloWorld

    基于故事板的HelloWorld工程 Storyboard(故事板)是用来替代xib的技术,也是iOS 5最重要的新特性之一.我们用Storyboard(故事板)重构HelloWorld. 使用故事板 ...

  4. iOS开发那些事-Passbook详解与开发案例

    Passbook是iOS 6的新功能,只能在iPhone和iPod touch设备中使用.它可以帮助我们管理商家发放的电子会员卡.积分卡. 优惠券等.这将对未来电子商务产生深远的影响.商家通过发放会员 ...

  5. iOS开发那些事-Passbook详解与开发案例(附视频)

    Passbook是iOS 6的新功能,只能在iPhone和iPod touch设备中使用.它可以帮助我们管理商家发放的电子会员卡.积分卡.优惠券等.这将对未来电子商务产生深远的影响.商家通过发放会员卡 ...

  6. iOS开发 搭建视频直播系统,基于LFLiveKit+ijkplayer+rtmp(iOS端)

    本文主要使用的三个技术: 推流:LFLiveKit 播放:ijkplayer 服务器:nginx+rtmp+ffmpeg 有了这三点技术就可以完成一个简约的直播系统.效果图如下(右边的是用模拟器设备运 ...

  7. iOS开发那些事-表视图UI设计模式

    软件设计中有设计模式,在UI设计方面也有设计模式.由于表视图的应用在iOS中极其广泛,本节向大家介绍表视图中两个UI设计模式:分页模式和下拉刷新(Pull-to-Refresh)模式.这两种模式已经成 ...

  8. iOS开发那些事--iOS6 UI状态保持和恢复

    iOS设计规范中要求,当应用退出的时候(包括被终止运行时候),画面中UI元素状态需要保持的,当再次进来的时候看状态与退出是一样的.iOS6之后苹果提供以下API使得UI状态保持和恢复变得很容易了. 在 ...

  9. iOS开发那些事-Git在Xcode中的配置与使用

    很多Git命令都是在命令行下运行的,命令行下管理Git有很多优点不用多说.但最大的缺点是要求用户记住这些命令.因此Git图形界面还是很受一 些用户欢迎的,其中Xcode作为集成开发环境工具,也提供了一 ...

最新文章

  1. python实现文件下载-python实现文件下载的方法总结
  2. 图解web前端开发工具教程
  3. 2018.4.23 数据结构
  4. 迁移solaris ufs根文件系统至zfs根文件系统
  5. 【Python实例第16讲】特征集聚
  6. 机器学习- 吴恩达Andrew Ng 编程作业技巧 for Week3
  7. python安装包————————百度网盘
  8. SQL中的n+1次select语句查询问题
  9. Apple Pay 详解
  10. python文件同时读写_python可以同时对文件进行读写操作吗
  11. BZOJ 3162:独钓寒江雪
  12. 根据url生成二维码,扫描打开url的两种方法编辑器
  13. excel查找命令_快速查找Excel功能区命令
  14. 霹雳吧啦Wz语义分割学习笔记P8
  15. xml在线格式化工具
  16. 科技云报道:数字化转型提速,深信服有答案
  17. OPNsense用户手册-Netflow导出和分析
  18. Kafka---如何配置Kafka集群和zookeeper集群
  19. 2021阿里云供应链大赛--需求预测与单级库存优化参赛总结
  20. php 清除js,php,js清除cookie

热门文章

  1. freertos之任务
  2. 洛谷P2835 刻录光盘
  3. 解析利用wsdl.exe生成webservice代理类的详解
  4. Linux权限管理 - 特殊权限之文件特殊权限
  5. iOS—OC——C——野指针
  6. 新手学逆向,调试abexcm1过程
  7. 【BZOJ】【2154】Crash的数字表格
  8. DevExpress 里实现单选按钮
  9. 美团点评资深产品专家刘远飞:了解业务要弄清楚这三个问题
  10. PMCAFF出品|十一月30篇爆款文章合集,干货、技能、内涵齐飞,总有一款适合你