之前我们已经讲过UIPageViewController,那篇文章演示了如何使用Interface Builder创建UIPageViewController。为了适配iOS7和Xcode5,我们重新写了这篇新教程——使用Storyboard创建UIPageViewController。
你第一次打开一个app的时候,一定会发现一系列的引导页(或者是操作指南)来给你介绍一些这个app的特性,这是给用户介绍app功能的通常做法。这篇文章中,我们就来看看如何用UIPageViewController创建一个类似的引导页面。
UIPageViewController在iOS 5 SDK中首次引入,它使得开发者可以使用这个ViewController创建分页视图。在iOS 6中,这个类有了更新,支持滚动过渡效果。使用Page View,用户可以方便的通过手势在多个页面之间导航。UIPageViewController并不仅仅用于引导页,很多游戏,例如:愤怒的小鸟,就是 用Page View来展示关卡选择的页面,还有有关书籍的应用,用这个类来显示书的页面。
example
UIPageViewController是个高度可配置的类,你可以进行如下配置:
- 分页的方向——水平或垂直
- 翻页的样式——书卷翻页或者滑动翻页
- 书脊位置——只有书卷翻页样式有效
- 页面间距——只有滑动翻页样式有效,用来定义页面间距(inter-page spacing)
为了演示,我们会一起创建一个简单的app。当然,我们不会演示所有的UIPageViewController的配置细节,我们会演示到使用滑动 翻页样式来创建一个引导页。不过别担心,有了对UIPageViewController的基本理解,我相信你能够去探索其他的特性。
开始吧!
Demo一览
我们要创建的Demo很简单,它会显示4个页面来介绍app的UI。用户可以在页面之间滑动切换。在任何时候用户点击“Start again”按钮会回到第一页。你能在Snapguide或Airbnb等app中找到很多类似的引导页,所以这个效果你应该不陌生。
创建项目
打开Xcode并创建一个Simple View Application项目。选择Single View Application看起来有点奇怪,因为Xcode已经提供了基于UIPageViewController的具有完整功能的Page-Based Application模板。但是,这个模板还是有一些复杂,把这个模板解释清楚比重新开始一个项目要复杂的多。况且,从零开始一定会让我们对 UIPageViewController的使用有更好的掌握。
好了,开始吧。下个页面中输入PageViewDemo作为项目名称,在company identifier栏中填入com.appcoda,设备类型选择iPhone。点击下一步并创建项目。
在Storyboard中创建Page View Controller
下一步,选择Main.storyboard。通常,你会看到一个默认的由Xcode生成的View Controller,先别管它,从Object Library拖出一个Page View Controller到Storyboard中。然后再拖出另一个View Controller。
在这个项目中,第一个View Controller会作为根View Controller,承载Page View Controller。最后添加的View Controller会作为页面的内容。后文中,用“根VC”代表“第一个View Controller”,“内容VC”代表“最后添加的View Controller”。
你可能会疑惑为什么只添加1个View Controller作为4页的内容,难道不应该使用4个View Controller吗?通过后面的演示你会发现,引导页都非常相似,通过复用这个View Controller显然是更好的选择。
下一步,给内容VC和Page View Controller分别设置一个ID。你能在Identity Inspector面板方便地设置。将Page View Controller的ID设置为“PageViewController”,将内容VC的ID设置为“PageContentController”。 后面我们会在代码中使用到这些ID。
Page View Controller的默认变换样式是翻页效果(Page Curl),这个效果比较适合书籍类应用。引导页中,使用滑动效果更合适,所以将transition style更改为Scroll。
现在来设计内容vc的界面。拖出一个Image View和一个Label到Controller中。按照喜好更改字体和字号。但是你的View Controller应该和下面截图的样子类似。
对于那个默认的View Controller,在底部添加一个“Start again”按钮。
编写View Controller类
下一步是编写View Controller类并和对应的View Controller绑定。在菜单栏中选择File -> New -> File… 之后选择“Objective-C class”模板。命名为PageContentViewController,并使这个类继承自UIViewController。
返回Storyboard,选择内容VC并在Identify Inspector中设置Custom Class项为PageContentViewController。
下一步,我们为Image View和Label创建outlet。切换到(辅助编辑)Assistant Editor模式并确保PageContentViewController.h文件已经打开。按住Control键从Image View拖动到PageContentViewController.h创建IBOutlet。设置名字分别为backgroundImageView和 titleLabel。
经过上面的编辑,PageContentViewController.h文件应该像下面这样:
下一步,选择根VC并确保ViewController.h已经打开了。创建从“Start again”按钮的action,命名为“startWalkthrough”。
好了,我们已经完成了UI的设计,并已经创建好了outlet,开始实现View Controller类吧。
实现Page Content View Controller
实现PageContentViewController非常简单第一步,像PageContentViewController.h中添加以下属性:
pageIndex属性用来储存当前页面的索引(位置)。因为这个View Controller用来显示一张图片和一个标题,所以我们创建两个属性分别用来接收titleText和imageFile。下一步,打开 PageContentViewController.m,将viewDidLoad:方法修改成这样:
实现Page View Controller
UIPageViewController的定位是Controller的容器。这个容器用来包含和管理要在app中显示的多个View Controller,同时,控制一个View Controller切换到另一个View Controller的方式。这里的UIPageViewController就是让用户可以在页面间导航的容器,每个页面都由对应的View Controller对象管理。下面的插图说明了Page View Controller和内容VC之间的关系。
在UIPageViewController开始工作之前,我们必须实现UIPageViewControllerDataSource协议。 PageViewController的Data Source负责按照(PageViewController的)需要提供内容VC。我们通过实现Data Source协议告知PageViewController每个页面显示什么内容。
在这个例子中,我们使用ViewController类作为UIPageViewController的Data Source。因此需要声明在ViewController类中声明它实现了UIPageViewControllerDateSource协议。
ViewController类还负责向内容VC提高数据(图片和标题)。打开ViewController.h,修改@interface声明,添加一个新的属性来保存UIPageViewController,同样的,创建图片和标题的属性。
在ViewController.m文件中,在viewDidLoad:方法中初始化标题和图片:
注意:你能在这个链接下载这些图片并添加到你的Xcode项目中。
我们已经创建好了页面内容的数据模型。下一步,我们要至少实现UIPageViewControllerDataSource的以下两个方法:
- viewControllerAfterViewController – 提供当前View Controller的后一个View Controller。换言之,我们告诉app下一页显示什么内容。
- viewControllerBeforeViewController – 提供当前View Controller的前一个View Controller。换言之,我们告诉app上一页显示什么内容。
在ViewController.m文件的@end之前,添加如下代码:
上面的方法非常简单。首先,我们获取当前的页码,简单地增加/减少页码并返回要显示的View Controller。当然,我们需要做边缘检查,并在超出时返回nil。
正如你注意到的那样,我们还没有创建viewControllerAtIndex:方法。这是一个用来创建所需位置的内容VC的辅助方法。它接收一个index参数并创建对应的内容VC。
在ViewController.m文件中,添加这个辅助方法:
还记得吗,我们在设计UI时为这些View Controller设置了ID。这个ID用于创建View Controller对象时的引用。为了实例化一个View Controller对象,你需要使用instantiateViewControllerWithIdentifier:方法,并传入一个ID。
为了显示页面指示器(Page Indicator),你需要告诉iOS Page View Controller要显示的页面的数量(也就是点的数量),以及初始选择那一页。在ViewController.m的底部添加以下两个方法:
同样的,上面两个方法也非常简单。我们仅仅是告诉iOS我们一共需要显示多少页面,以及默认选择的第一页。
注意:你必须实现上面的方法才能显示页面指示器(Page Indicator)。而且,页面指示器只在滑动切换模式下起作用。
初始化UIPageViewController
最后一步就是创建并初始化UIPageViewController,最好的位置就是viewDidLoad方法。打开ViewController.m文件,修改viewDidLoad:方法:
让我们看一下这个方法做了什么。首先我们创建了PageViewController实例。随后我们制定了Data Source,在这个例子中就是这个类本身。然后我们创建了第一个内容VC并把它添加到一个Controller数组中,并且将它和要显示的 ViewController关联。
最后,我们修改内容VC的大小并将内容VC的view添加到当前view中。
自定义Page Indicator
如果你现在编译并运行这个app,它会正常运行但是你可能会发现页面指示器并没有显示。事实上页面指示器已经显示了但是点的颜色和view的颜色一样,所以让我们来修改它的颜色吧。
在AppDelegate.m文件中,在didFinishLaunchingWithOptions:方法中添加下面几行代码:
编译并运行这个app
好了,启动这个应用然后看UIPageViewController运行得如何。你应该可以在iPhone模拟器中加载Page View Controller了。尝试在多个页面之间滑动一下。
返回首页
还有一件事没做。“Start again”按钮还没有实现功能。点击的时候,我们希望Page View Controller滑动到第一页。你可以使用UIPageViewController的setViewControllers:方法切换页面。为了回 到第一页,修改ViewController.m的startWalkthrough:方法:
再次运行app。点击“Start again”按钮会将你带回第一页。
总结
这篇教程中,我们介绍了UIPageViewController的基础知识并演示了如何使用Storyboard创建Controller。 UIPageViewController是实现引导页的非常方便的类。同时,UIPageViewController的适用范围非常广阔,你可以用它 来显示任意你想显示的信息,比如:多个网页。UIPageViewController还有丰富的配置项。这篇教程只涵盖了滑动样式,但是可别忘了你可以 使用这个类简单地创建一个读书应用呢!只需要将滑动样式更改为翻页样式就可以了。所以别满足于这个小例子,尝试修改并了解 UIPageViewController的其他选项吧。
如果需要完整参考,可以在这个链接下载Xcode项目。和往常一样,请将你的评论和想法告知我们。
Demo项目已本地到博主VPS,放心下载。