uipageviewcontroller是ios中少見的動畫視圖控制器之一,通過它既可以建立類似uiscrollview與uipagecontrol結合的滾屏視圖,也可以建立類似圖書效果的炫酷翻頁視圖。uipageviewcontroller類似一個視圖容器,其中每個具體的視圖由各自的viewcontroller進行維護管理,uipageviewcontroller隻進行協調與動畫布置。下圖可以很好的展現出uipageviewcontrolelr的使用結構:
上圖中,uipageviewcontrollerdatasource協定為uipageviewcontroller提供資料支援,datasource協定提供的資料來自各個viewcontoller自行維護,uipageviewcontrollerdelegate中的回調可以對翻頁動作,螢幕旋轉動作等進行監聽。uipageviewcontroller把從datasource中擷取到的視圖資料渲染給view用于目前視圖控制器的展示。
首先建立一個類作為翻頁視圖控制器中具體每一頁視圖的控制器,使其繼承于uiviewcontroller:
modelviewcontroller.h
<a href="http://my.oschina.net/u/2340880/blog/630563#">?</a>
1
2
3
4
5
<code>#import <uikit/uikit.h></code>
<code>@interface modelviewcontroller : uiviewcontroller</code>
<code>+(modelviewcontroller *)creatwithindex:(</code><code>int</code><code>)index;</code>
<code>@property(nonatomic,strong)uilabel * indexlabel;</code>
<code>@end</code>
modelviewcontroller.m
6
7
8
9
10
11
12
13
14
15
16
17
<code>#import "modelviewcontroller.h"</code>
<code>@interface modelviewcontroller ()</code>
<code>@implementation modelviewcontroller</code>
<code>+(modelviewcontroller *)creatwithindex:(</code><code>int</code><code>)index{</code>
<code> </code><code>modelviewcontroller * con = [[modelviewcontroller alloc]init];</code>
<code> </code><code>con.indexlabel = [[uilabel alloc]initwithframe:cgrectmake(110, 200, 100, 30)];</code>
<code> </code><code>con.indexlabel.text = [nsstring stringwithformat:@</code><code>"第%d頁"</code><code>,index];</code>
<code> </code><code>[con.view addsubview:con.indexlabel];</code>
<code> </code><code>return</code> <code>con;</code>
<code>}</code>
<code>- (</code><code>void</code><code>)viewdidload {</code>
<code> </code><code>[super viewdidload];</code>
<code> </code><code>// do any additional setup after loading the view.</code>
<code> </code><code>self.view.backgroundcolor = [uicolor redcolor];</code>
在工程模闆自帶的viewcontroller.m檔案中實作如下代碼:
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<code>#import "viewcontroller.h"</code>
<code>//遵守協定</code>
<code>@interface viewcontroller ()<uipageviewcontrollerdatasource,uipageviewcontrollerdelegate></code>
<code>{</code>
<code> </code><code>//翻頁視圖控制器對象</code>
<code> </code><code>uipageviewcontroller * _pageviewcontrol;</code>
<code> </code><code>//資料源數組</code>
<code> </code><code>nsmutablearray * _dataarray;</code>
<code>@implementation viewcontroller</code>
<code> </code><code>//進行初始化</code>
<code> </code><code>_pageviewcontrol = [[uipageviewcontroller alloc]initwithtransitionstyle:uipageviewcontrollertransitionstylescroll navigationorientation:uipageviewcontrollernavigationorientationhorizontal options:@{uipageviewcontrolleroptionspinelocationkey:@0,uipageviewcontrolleroptioninterpagespacingkey:@10}];</code>
<code> </code><code>self.view.backgroundcolor = [uicolor greencolor];</code>
<code> </code><code>//設定翻頁視圖的尺寸</code>
<code> </code><code>_pageviewcontrol.view.bounds=self.view.bounds;</code>
<code> </code><code>//設定資料源與代理</code>
<code> </code><code>_pageviewcontrol.datasource=self;</code>
<code> </code><code>_pageviewcontrol.delegate=self;</code>
<code> </code><code>//建立初始界面</code>
<code> </code><code>modelviewcontroller * model = [modelviewcontroller creatwithindex:1];</code>
<code> </code><code>//設定初始界面</code>
<code> </code><code>[_pageviewcontrol setviewcontrollers:@[model] direction:uipageviewcontrollernavigationdirectionreverse animated:yes completion:nil];</code>
<code> </code><code>//設定是否雙面展示</code>
<code> </code><code>_pageviewcontrol.doublesided = no;</code>
<code> </code><code>_dataarray = [[nsmutablearray alloc]init];</code>
<code> </code><code>[_dataarray addobject:model];</code>
<code> </code><code>[self.view addsubview:_pageviewcontrol.view];</code>
<code>//翻頁控制器進行向前翻頁動作 這個資料源方法傳回的視圖控制器為要顯示視圖的視圖控制器</code>
<code>- (nullable uiviewcontroller *)pageviewcontroller:(uipageviewcontroller *)pageviewcontroller viewcontrollerbeforeviewcontroller:(uiviewcontroller *)viewcontroller{</code>
<code> </code><code>int</code> <code>index = (</code><code>int</code><code>)[_dataarray indexofobject:viewcontroller];</code>
<code> </code><code>if</code> <code>(index==0) {</code>
<code> </code><code>return</code> <code>nil;</code>
<code> </code><code>}</code><code>else</code><code>{</code>
<code> </code><code>return</code> <code>_dataarray[index-1];</code>
<code> </code><code>}</code>
<code>//翻頁控制器進行向後翻頁動作 這個資料源方法傳回的視圖控制器為要顯示視圖的視圖控制器</code>
<code>- (nullable uiviewcontroller *)pageviewcontroller:(uipageviewcontroller *)pageviewcontroller viewcontrollerafterviewcontroller:(uiviewcontroller *)viewcontroller{</code>
<code> </code><code>if</code> <code>(index==9) {</code>
<code> </code><code>if</code> <code>(_dataarray.count-1>=(index+1)) {</code>
<code> </code><code>return</code> <code>_dataarray[index+1];</code>
<code> </code><code>}</code><code>else</code><code>{</code>
<code> </code><code>modelviewcontroller * model = [modelviewcontroller creatwithindex:index+2];</code>
<code> </code><code>[_dataarray addobject:model];</code>
<code> </code><code>return</code> <code>model;</code>
<code> </code><code>}</code>
<code>//螢幕旋轉觸發的代理方法</code>
<code>- (uipageviewcontrollerspinelocation) pageviewcontroller:(uipageviewcontroller *)pageviewcontroller spinelocationforinterfaceorientation:(uiinterfaceorientation)orientation{</code>
<code> </code><code>return</code> <code>uipageviewcontrollerspinelocationmin;</code>
<code>//設定分頁控制器的分頁數</code>
<code>- (nsinteger)presentationcountforpageviewcontroller:(uipageviewcontroller *)pageviewcontroller {</code>
<code> </code>
<code> </code><code>return</code> <code>10;</code>
<code>//設定初始的分頁點</code>
<code>- (nsinteger)presentationindexforpageviewcontroller:(uipageviewcontroller *)pageviewcontroller{</code>
<code> </code><code>return</code> <code>0;</code>
上面建立了最簡單的翻頁視圖控制器示例,效果如下圖:
<code>//建立翻頁視圖控制器對象</code>
<code>- (instancetype)initwithtransitionstyle:(uipageviewcontrollertransitionstyle)style navigationorientation:(uipageviewcontrollernavigationorientation)navigationorientation options:(nullable nsdictionary<nsstring *, id> *)options;</code>
上面方法用于建立視圖控制器對象,其中uipageviewcontrollertransitionstyle參數設定翻頁控制器的風格,枚舉如下:
<code>typedef</code> <code>ns_enum(nsinteger, uipageviewcontrollertransitionstyle) {</code>
<code> </code><code>uipageviewcontrollertransitionstylepagecurl = 0, </code><code>//類似于書本翻頁效果</code>
<code> </code><code>uipageviewcontrollertransitionstylescroll = 1 </code><code>// 類似于scrollview的滑動效果</code>
<code>};</code>
如果設定為uipageviewcontrollertransitionstylecurl,翻頁效果如下圖所示:
上面初始化方法中的uipageviewcontrollernavigationorientation屬性設定翻頁的方向,枚舉如下:
<code>typedef</code> <code>ns_enum(nsinteger, uipageviewcontrollernavigationorientation) {</code>
<code> </code><code>uipageviewcontrollernavigationorientationhorizontal = 0,</code><code>//水準翻頁</code>
<code> </code><code>uipageviewcontrollernavigationorientationvertical = 1</code><code>//豎直翻頁</code>
options參數用于設定翻頁視圖控制器的配置字典,其可以設定的配置鍵值如下:
<code>//這個鍵需要設定為uipageviewcontrolleroptionspinelocationkey枚舉值對應的nsnumber對象 設定翻頁控制器的書軸 後面會介紹</code>
<code>nsstring * </code><code>const</code> <code>uipageviewcontrolleroptionspinelocationkey;</code>
<code>//這個鍵需要設定為nsnumber類型 設定每頁視圖的間距 用于滾動視圖風格的</code>
<code>nsstring * </code><code>const</code> <code>uipageviewcontrolleroptioninterpagespacingkey;</code>
下面是uipageviewcontroller的一些常用屬性與方法:
<code>//設定資料源</code>
<code>@property (nullable, nonatomic, weak) id <uipageviewcontrollerdelegate> delegate;</code>
<code>//設定代理</code>
<code>@property (nullable, nonatomic, weak) id <uipageviewcontrollerdatasource> datasource;</code>
<code>//擷取翻頁風格</code>
<code>@property (nonatomic, readonly) uipageviewcontrollertransitionstyle transitionstyle;</code>
<code>//擷取翻頁方向</code>
<code>@property (nonatomic, readonly) uipageviewcontrollernavigationorientation navigationorientation;</code>
<code>//擷取書軸類型</code>
<code>@property (nonatomic, readonly) uipageviewcontrollerspinelocation spinelocation;</code>
<code>//設定是否雙面顯示</code>
<code>@property (nonatomic, getter=isdoublesided) </code><code>bool</code> <code>doublesided;</code>
<code>//設定要顯示的視圖控制器</code>
<code>- (</code><code>void</code><code>)setviewcontrollers:(nullable nsarray<uiviewcontroller *> *)viewcontrollers direction:(uipageviewcontrollernavigationdirection)direction animated:(</code><code>bool</code><code>)animated completion:(</code><code>void</code> <code>(^ __nullable)(</code><code>bool</code> <code>finished))completion;</code>
上面隻有spinelocation屬性有些難于了解,其枚舉如下:
<code>typedef</code> <code>ns_enum(nsinteger, uipageviewcontrollerspinelocation) {</code>
<code> </code><code>//對于scrollview類型的滑動效果 沒有書軸 會傳回下面這個枚舉值</code>
<code> </code><code>uipageviewcontrollerspinelocationnone = 0, </code>
<code> </code><code>//以左邊或者上邊為軸進行翻轉 界面同一時間隻顯示一個view</code>
<code> </code><code>uipageviewcontrollerspinelocationmin = 1, </code>
<code> </code><code>//以中間為軸進行翻轉 界面同時可以顯示兩個view</code>
<code> </code><code>uipageviewcontrollerspinelocationmid = 2, </code>
<code> </code><code>//以下邊或者右邊為軸進行翻轉 界面同一時間隻顯示一個view</code>
<code> </code><code>uipageviewcontrollerspinelocationmax = 3 </code>
将上面的示例代碼修改幾個地方如下:
<code> </code><code>// do any additional setup after loading the view, typically from a nib.</code>
<code> </code><code>_pageviewcontrol = [[uipageviewcontroller alloc]initwithtransitionstyle:uipageviewcontrollertransitionstylepagecurl navigationorientation:uipageviewcontrollernavigationorientationvertical options:@{uipageviewcontrolleroptionspinelocationkey:@2,uipageviewcontrolleroptioninterpagespacingkey:@10}];</code>
<code> </code><code>modelviewcontroller * model2 = [modelviewcontroller creatwithindex:2];</code>
<code> </code><code>[_pageviewcontrol setviewcontrollers:@[model,model2] direction:uipageviewcontrollernavigationdirectionreverse animated:yes completion:nil];</code>
<code> </code><code>_pageviewcontrol.doublesided = yes;</code>
<code> </code><code>return</code> <code>uipageviewcontrollerspinelocationmid;</code>
運作效果如下圖所示:
<code>//向前翻頁展示的viewcontroller</code>
<code>- (nullable uiviewcontroller *)pageviewcontroller:(uipageviewcontroller *)pageviewcontroller viewcontrollerbeforeviewcontroller:(uiviewcontroller *)viewcontroller;</code>
<code>//向後翻頁展示的viewcontroller</code>
<code>- (nullable uiviewcontroller *)pageviewcontroller:(uipageviewcontroller *)pageviewcontroller viewcontrollerafterviewcontroller:(uiviewcontroller *)viewcontroller;</code>
<code>//設定分頁控制器的分頁點數</code>
<code>- (nsinteger)presentationcountforpageviewcontroller:(uipageviewcontroller *)pageviewcontroller ns_available_ios(6_0);</code>
<code>//設定目前分頁控制器所高亮的點</code>
<code>- (nsinteger)presentationindexforpageviewcontroller:(uipageviewcontroller *)pageviewcontroller ns_available_ios(6_0);</code>
<code>//翻頁視圖控制器将要翻頁時執行的方法</code>
<code>- (</code><code>void</code><code>)pageviewcontroller:(uipageviewcontroller *)pageviewcontroller willtransitiontoviewcontrollers:(nsarray<uiviewcontroller *> *)pendingviewcontrollers ns_available_ios(6_0);</code>
<code>//翻頁動畫執行完成後回調的方法</code>
<code>- (</code><code>void</code><code>)pageviewcontroller:(uipageviewcontroller *)pageviewcontroller didfinishanimating:(</code><code>bool</code><code>)finished previousviewcontrollers:(nsarray<uiviewcontroller *> *)previousviewcontrollers transitioncompleted:(</code><code>bool</code><code>)completed;</code>
<code>//螢幕防線改變時回到的方法,可以通過傳回值重設書軸類型枚舉</code>
<code>- (uipageviewcontrollerspinelocation)pageviewcontroller:(uipageviewcontroller *)pageviewcontroller spinelocationforinterfaceorientation:(uiinterfaceorientation)orientation;</code>
<code></code>