一百、创建 基于页面视图控制器的应用程序

来源:互联网 发布:档案管理系统软件源码 编辑:程序博客网 时间:2024/09/21 08:57

在Xcode当中  创建  基于页面控制器的应用程序时,我们  有  一个选择  就是  利用  Xcode提供的基于页面的应用程序模板。当我们  选择  基于页面的应用程序模板后,Xcode  会生成  一个用12个页面显示一年中各个月份的应用程序。这个模板  使  人  感到  很奇怪,因为  这个模板所提供的  不仅是  一个我们在其之上创建应用程序的基础  而  相当于是  一个示例程序了。虽然  这  对于最初的学习  很有用,但是  除非  在12个页面上写上12个月的名称  正好  是  你所需要的,否则  我们  必须把  多余的功能  去除,然后  才能用于  其它用途。

与其选择  Xcode提供的基于页面的应用程序模板,我们  在这篇博文中  要选择  单视图应用程序模板  并且  在其之上  实现  页面功能。

创建  项目

我们  启动  Xcode  并且  创建  一个新的iOS单视图应用程序。我们  将  这个应用程序的产品名称  和  物件类型名称前缀  设定为  pageApp。我们  还要确保  使用故事板(Use Storyboard)选项  没有被选择。

添加  内容视图控制器

在这里这个例子当中  我们  要使用  一个视图控制器物件  向用户  展示  页面。这个视图控制器中的视图上  会包含  一个网页视图物件(UIWebView类型)  根据当前的页数  显示出  不同的html内容。另外  这个视图控制器物件  还需要  另外一个物件  来容纳  需要显示的html内容。

为了添加  这个视图控制器,我们  需要创建  一组Objective-c Class文件。创建  新的Objective-c Class文件时,将  Class选项  填写为  ContentViewController  并且  确保选择了  With XIB for user interface这个选项。

选择  ContentViewController.h这个文件  并且  将  这个文件  修改为  这样:

这样一来  每个ContentViewController类型的物件  都包含  一个网页视图物件webView  和  一个任意类型的数据物件dataObject。

接着  打开  ContentViewController.xib这个文件  再  从物件库中  拖  一个网页视图(Web View)  放  到画布中的视图上。

然后  按住  键盘上的control键  并且  用  鼠标  点住  File’s Owner图标  不放。再  将  鼠标光标  拖到  画布中的网页视图上  并且  放开  鼠标。最后  在弹出来的菜单中  选择  webView这个选项。

每次用户  在应用程序中  翻页时,适用于UIPageViewController类型物件的一项措施  都会得以实施  从而创建  一个新的ContentViewController类型的物件  并且  将  正确的html内容  存储  在这个ContentViewController物件所包含的数据物件dataObject当中  以便  网页视图物件webView  显示出来。而  在ContentViewController类型的物件所包含的视图  显示出来之前,适用于ContentViewController这类物件的措施viewWillAppear:  会得以执行,于是  我们  要在viewWillAppear:这项措施中  将  数据物件dataObject中的内容  存储  在网页视图物件webView当中。所以  我们  打开  ContentViewController.m这个文件  并且  在@implement命令之后  加入

这行语句,用以生成  webView、setWebView:  和  dataObject、setDataObject:这四项措施。

同时  还要在这个文件中  加入  viewWillAppear这项措施:

到目前  为止,我们  已经设计好了  内容视图控制器。下一步  我们  要设计  应用程序的数据模型。

创建  数据模型

这个应用程序的数据模型  由一个数组物件  构成,这个数据物件  包含  若干个字符串物件,其中  每个字符串物件  都是  需要显示在各个页面上的html内容。在我们这个例子当中  我们  把pageAppViewController类型的物件  用作  页面视图控制器的数据源。同时  由于这个原因  pageAppViewController这类物件  必须遵循  UIPageViewControllerDataSource这项协议,所以  我们  打开  pageAppViewController.h这个文件  并且  将  @interface这行语句  修改成  这样:

以表明  pageAppViewController这类物件  遵循  UIPageViewControllerDataSource这项协议。除此之外  我们  需要在@interface命令  和  @end命令之间  加入  这两行语句:

这样  每个pageAppViewController类型的物件  都会包含  一个页面控制器物件pageViewController  和  数组物件pageContent。其中  数组物件pageContent  用来存储  各个页面的html内容。同时  不要忘了  在pageAppViewController.m这个文件中的@implementation命令后  加入

接着  我们  要编写  一项适用于pageAppViewController这类物件的措施createContentPages:

在createContentPages这项措施中

这行语句  创建了  一个数组物件pageStrings  用于存储  每个页面所需的html内容。

接下来的for()循环  会运行  十次,每运行  一次,都会创建  一个包含html内容的字符串  并且  将  这个字符串  添加到  数组物件pageStrings当中。

这项措施中最后

这行语句  将  数组物件pageStrings的全部内容  存储  在createContentPages这项措施的实施对象所包含的数组物件pageContent当中。

另外  我们  还需要  在pageAppViewController类型物件中的视图加载后  对这个类型的物件  采取  createContentPages这项措施,于是  我们  将pageAppViewController.m这个文件中的viewDidLoad这项措施  修改为  这样:

现在  我们  为这个应用程序  设计好了  内容视图控制器  和  数据模型,接下来  我们  需要编写  为页面视图控制器提供数据的措施,也就是  UIPageViewControllerDataSource这项协议规定的两项措施,其中一项措施  用于生成  当前内容视图控制器之后的内容视图控制器,而另外一项措施  用于生成  当前内容视图控制器之前的内容视图控制器。

由于pageAppViewController这类物件  充当  页面视图控制器的数据源,所以  UIPageViewControllerDataSource这项协议规定的措施  必须适用于  pageAppViewController这类物件,于是  我们  要在pageAppViewController.m这个文件中  编写  这些措施。首先  我们  在pageAppViewController.m这个文件中  添加  这两项措施:

其中  indexOfViewController这项措施  会收到  ContentViewController类型的视图控制器contentViewController  并且  找到  这个视图控制器  是  第几个视图控制器。这  是  这样办到的:先  把  视图控制器contentViewController中的数据物件dataObject提取出来,然后  对数组物件pageContent  采取  indexOfObject:这项措施  从而  找出  当前视图控制器所包含的数据物件dataObject  是  数组物件pageContent中的第几个,于是  就知道  当前的视图控制器  就是  第几个视图控制器了。

viewControllerAtIndex:这项措施  会收到  NSUInteger类型的无标记整数  并且  存放 在变量index当中。然后  变量index的值  是  几,这项措施  就会生成  第几个内容视图控制器。在viewControllerAtIndex:这项措施中

这个if()语句  会判断  需要需要显示的页面数量  是否为  领  以及  变量index的值  是否超过了  需要显示的页面数量。如果  这两个条件  任意  满足  一个,则  将  nil  作为结果  传递回去,也就是  什么  都不传递回去。

接着

这行语句  利用  ContentViewController.xib这个文件中的设计  创建了  ContentViewController类型的内容视图控制器contentViewController。

这行语句  从数组物件pageContent  找出  当前页面需要显示的内容  并且  存储  在内容视图控制器contentViewController所包含的数据物件dataObject当中。

这行语句  则将  已经准备好了的内容视图控制器contentViewController  作为结果  传递回去。

刚刚编写的indexOfViewController:  和  viewControllerAtIndex:这两项措施  恰恰是  UIPageViewControllerDataSource这项协议所规定的措施中需要用到的。接下来  我们  编写  UIPageViewControllerDataSource这项协议所规定的两项措施。这两项措施  依然  写  在pageAppViewController.m这个文件中:

其中  viewControllerBeforeViewController:viewController这项措施实施后,我们  可以得到  viewController这个内容视图控制器之前的内容视图控制器。而  viewControllerAfterViewController:viewController这项措施实施后,我们  可以得到  viewController这个内容视图控制器之后的内容控制器。

在viewControllerBeforeViewController:viewController这项措施中

这行语句  检查  当前收到的内容视图控制器  是  第几个  并且  将  结果  存储  在变量index当中。

这个if()语句  检查  index的值  是否是  有效的值,如果  不是,则  什么  也不传递回去。

这两行语句  生成了  第index-1个内容视图控制器  并且  作为结果  传递回去。

在viewControllerBeforeViewController:viewController这项措施当中

这几行语句  先  检查  当前收到内容视图控制器  是  第几个内容视图控制器  并且  将  结果  存储  在变量index。接着  检查  当前  是不是收到了  内容视图控制器,如果  没有收到,也就是  变量index的值  为  常熟NSNotFound,则  什么  也不传递回去。

这几行语句  先  检查  index+1的值  是否超过了  所有内容视图控制器的数量,如果  没有超过,则创建  第index+1个内容视图控制器  并且  作为结果  传递回去。

创建  并且  初始化  页面视图控制器

整个应用程序的最后一步  就是  创建  一个页面视图控制器,也就是  UIPageViewController类型的物件  并且  正确地  对其  初始化。因为  应用程序  启动后,第一个呈现在用户面前的视图  就是  pageAppViewController类型视图控制器所包含的视图,而  pageAppViewController类型视图控制器中的视图  一加载完毕,适用于这类视图控制器的措施viewDidLoad:  就会得以实施,所以  我们  在viewDidLoad:这项措施中  创建  并且  初始化  页面视图控制器。我们  需要将  viewDidLoad:这项措施  在原来的基础之上  修改为  这样:

在编译  并且  运行  这个程序之前,我们  需要花一点  时间  来分析一下  viewDidLoad:这项措施中的代码。

这行语句  创建了  一个NSDictionary类型的物件options  用来存储  UIPageViewControllerOptionSpineLocationKey这个选项。UIPageViewControllerOptionSpineLocationKey这个选项  代表了  页面视图控制器中  “书脊”的位置。我们  这里  将  UIPageViewControllerOptionSpineLocationKey的值  设定为了  UIPageViewControllerSpineLocationMin,这  表明  我们  将  “书脊”的位置  设定  在页面视图控制器的最左边。

这行语句  为页面视图控制器  分配了  内存地址  并且  对其  采取了  initWithTransitionStyle:navigationOrientation:options这项措施。其中  第一个参数UIPageViewControllerTransitionStylePageCurl  表明  两个视图之间切换的效果  为  “翻页”的效果;第二个参数UIPageViewControllerNavigationOrientationHorizontal  表明  翻页的方向  为  左右翻页,而不是  上下翻页;第三个参数options中  则存储了  页面视图控制器的“书脊”位置。

这行语句  将  页面视图控制器pageViewController的数据源  设定为了  pageAppViewController类型的视图控制器。

这行语句  先获取了  pageAppViewController类型视图控制器所包含的视图,然后  对其  采取了  bounds这项措施  从而  获得  这个视图的大小  和  位置。最后  将  页面视图控制器pageViewController中的视图view的大小  和  位置  设定为  刚刚获得的数值。

在页面视图控制器  显示出来之前,我们  必须手工创建  第一个内容视图控制器,而

这行语句  就创建了  第一个内容视图控制器initialViewController。

这行语句  将  第一个内容视图控制器initialViewController  装入  数组物件viewControllers当中。接着  包含着第一个内容视图控制器的数组物件  需要装入  页面视图控制器pageViewController:

第一个参数UIPageViewControllerNavigationDirectionForward  将  导航方向  设定为了  正向。

这行语句  将  pageAppViewController类型的视图控制器的子视图控制器  设定为  页面视图控制器pageViewController。

这行语句  将  页面视图控制器pageViewController所包含的视图view  作为子视图  添加到  pageAppViewController类型视图控制器所包含的视图上。

将  子视图控制器  添加到  主视图控制器中后,我们  需要对子视图控制器  采取  didMoveToParentViewController:这项措施  并且  将  主视图控制器  作为参数。

编译  并且  运行  这个程序

编译  并且  运行  这个程序后,我们  可以看到  这样的效果:

UIPageViewController


原创粉丝点击