天天看點

iOS翻頁視圖控制器UIPageViewController的應用

    uipageviewcontroller是ios中少見的動畫視圖控制器之一,通過它既可以建立類似uiscrollview與uipagecontrol結合的滾屏視圖,也可以建立類似圖書效果的炫酷翻頁視圖。uipageviewcontroller類似一個視圖容器,其中每個具體的視圖由各自的viewcontroller進行維護管理,uipageviewcontroller隻進行協調與動畫布置。下圖可以很好的展現出uipageviewcontrolelr的使用結構:

iOS翻頁視圖控制器UIPageViewController的應用

上圖中,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 &lt;uikit/uikit.h&gt;</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 ()&lt;uipageviewcontrollerdatasource,uipageviewcontrollerdelegate&gt;</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&gt;=(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>

上面建立了最簡單的翻頁視圖控制器示例,效果如下圖:

iOS翻頁視圖控制器UIPageViewController的應用

<code>//建立翻頁視圖控制器對象</code>

<code>- (instancetype)initwithtransitionstyle:(uipageviewcontrollertransitionstyle)style navigationorientation:(uipageviewcontrollernavigationorientation)navigationorientation options:(nullable nsdictionary&lt;nsstring *, id&gt; *)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,翻頁效果如下圖所示:

iOS翻頁視圖控制器UIPageViewController的應用

上面初始化方法中的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 &lt;uipageviewcontrollerdelegate&gt; delegate;</code>

<code>//設定代理</code>

<code>@property (nullable, nonatomic, weak) id &lt;uipageviewcontrollerdatasource&gt; 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&lt;uiviewcontroller *&gt; *)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>

運作效果如下圖所示:

iOS翻頁視圖控制器UIPageViewController的應用

<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&lt;uiviewcontroller *&gt; *)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&lt;uiviewcontroller *&gt; *)previousviewcontrollers transitioncompleted:(</code><code>bool</code><code>)completed;</code>

<code>//螢幕防線改變時回到的方法,可以通過傳回值重設書軸類型枚舉</code>

<code>- (uipageviewcontrollerspinelocation)pageviewcontroller:(uipageviewcontroller *)pageviewcontroller spinelocationforinterfaceorientation:(uiinterfaceorientation)orientation;</code>

<code></code>

繼續閱讀