一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - IOS - ios電子書翻頁(yè)效果代碼詳解

ios電子書翻頁(yè)效果代碼詳解

2021-04-19 19:15iOS開發(fā)網(wǎng) IOS

這篇文章主要介紹了ios電子書翻頁(yè)效果代碼實(shí)現(xiàn)過程以及對(duì)應(yīng)的代碼講解,有需要的朋友參考下。

近實(shí)現(xiàn)了一個(gè)完整的電子書閱讀器,支持txt和epub格式的電子書閱讀,其中epub支持圖文混排的方式展示。本文主要談?wù)勂渲袃煞N翻頁(yè)效果的實(shí)現(xiàn),分別為仿真翻頁(yè)和水平滑動(dòng)翻頁(yè)。

仿真翻頁(yè)

最合適的方案就是使用系統(tǒng)提供的uipageviewcontroller了,不過默認(rèn)的uipageviewcontroller翻頁(yè)時(shí)背面是白色的,而閱讀器通常都會(huì)有背景色或背景圖片,翻頁(yè)時(shí)用戶體驗(yàn)就很糟糕,比如就像下面這樣

ios電子書翻頁(yè)效果代碼詳解

所以接下來主要說說如何修改背面顏色以達(dá)到美觀的翻頁(yè)效果。

uipageviewcontroller有一個(gè)屬性叫做isdoublesided,默認(rèn)為yes,也就是內(nèi)容只會(huì)在單面(正面)顯示,設(shè)置為no后,內(nèi)容便可以正面和背面雙面顯示,這時(shí)每翻一頁(yè),pageview的下面兩個(gè)回調(diào)會(huì)調(diào)用兩次

?
1
2
3
4
5
6
7
8
9
10
func pageviewcontroller(_ pageviewcontroller: uipageviewcontroller, viewcontrollerbefore viewcontroller: uiviewcontroller) -> uiviewcontroller?
{
  // 第一次回調(diào)索取背面的controller
  // 第二次回調(diào)索取正面的controller
}
func pageviewcontroller(_ pageviewcontroller: uipageviewcontroller, viewcontrollerafter viewcontroller: uiviewcontroller) -> uiviewcontroller?
{
  // 第一次回調(diào)索取背面的controller
  // 第二次回調(diào)索取正面的controller
}

所以我們可以對(duì)正面的controller進(jìn)行反向截圖,并將其放在背面的controller上顯示,這樣整體翻頁(yè)效果就會(huì)很美觀了。
代碼示例

?
1
2
3
4
5
6
7
8
9
10
11
12
13
// 對(duì)輸入的controller進(jìn)行反向截圖
func grabviewcontroller(viewcontroller: duapageviewcontroller) -> void {
  self.index = viewcontroller.index
  self.chapterbelong = viewcontroller.chapterbelong
  let rect = viewcontroller.view.bounds
  uigraphicsbeginimagecontextwithoptions(rect.size, true, 0.0)
  let context = uigraphicsgetcurrentcontext()
  let transform = cgaffinetransform(a: -1.0, b: 0.0, c: 0.0, d: 1.0, tx: rect.size.width, ty: 0.0)
  context?.concatenate(transform)
  viewcontroller.view.layer.render(in: context!)
  self.backimage = uigraphicsgetimagefromcurrentimagecontext()
  uigraphicsendimagecontext()
 }

效果像下面這樣

ios電子書翻頁(yè)效果代碼詳解

左右平滑翻頁(yè)

最初采用的是uipageviewcontroller的另一種翻頁(yè)模式——滾動(dòng)模式。該模式蘋果在底層是用scrollview實(shí)現(xiàn)的。但這種模式在頁(yè)面切換時(shí)存在一些問題,由于蘋果會(huì)對(duì)相鄰的controller進(jìn)行緩存,當(dāng)調(diào)用open func setviewcontrollers(_ viewcontrollers: [uiviewcontroller]?, direction: uipageviewcontrollernavigationdirection, animated: bool, completion: ((bool) -> swift.void)? = nil)方法并且動(dòng)畫為true時(shí),有時(shí)蘋果會(huì)錯(cuò)誤的認(rèn)為它已經(jīng)有了頁(yè)面的緩存而不再執(zhí)行數(shù)據(jù)源方法,從而引發(fā)一些問題,更詳細(xì)的說明可以看這篇文章,因此決定自己寫一個(gè)翻頁(yè)控件

duatranslationcontroller

duatranslationcontroller并沒有采用scrollview的方式實(shí)現(xiàn),而是基于controller容器,通過替換child controller來實(shí)現(xiàn),具體來說就是當(dāng)用戶點(diǎn)擊或者滑動(dòng)時(shí),判斷需要展示上一個(gè)頁(yè)面還是下一個(gè)頁(yè)面,然后模仿uipageviewcontroller通過回調(diào)的方式索取controller,加入到controller容器中,并通過動(dòng)畫的方式將新的controller平滑移動(dòng)進(jìn)入屏幕,舊的controller同時(shí)移出,如下是單擊手勢(shì)代碼示例(滑動(dòng)手勢(shì)涉及和用戶交互,邏輯更復(fù)雜些,但基本思路是一致的)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
@objc func handletapges(gesture: uitapgesturerecognizer) -> void {
  let hitpoint = gesture.location(in: gesture.view)
  let curcontroller = self.childviewcontrollers.first!
  
  if hitpoint.x < gesture.view!.frame.size.width/3 {
//   滑向上一個(gè)controller
   let lastcontroller = self.delegate?.translationcontroller(translationcontroller: self, controllerbefore: curcontroller)
   if lastcontroller != nil {
    self.delegate?.translationcontroller(translationcontroller: self, willtransitionto: lastcontroller!)
    self.setviewcontroller(viewcontroller: lastcontroller!, direction: .right, animated: allowanimating, completionhandler: {(complete) in
     self.delegate?.translationcontroller(translationcontroller: self, didfinishanimating: complete, previouscontroller: curcontroller, transitioncompleted: complete)
    })
   }
   
  }
  if hitpoint.x > gesture.view!.frame.size.width*2/3 {
//   滑向下一個(gè)controller
   let nextcontroller: uiviewcontroller? = self.delegate?.translationcontroller(translationcontroller: self, controllerafter: self.childviewcontrollers.first!)
   if nextcontroller != nil {
    self.delegate?.translationcontroller(translationcontroller: self, willtransitionto: nextcontroller!)
    self.setviewcontroller(viewcontroller: nextcontroller!, direction: .left, animated: allowanimating, completionhandler: {(complete) in
 
     self.delegate?.translationcontroller(translationcontroller: self, didfinishanimating: complete, previouscontroller: curcontroller, transitioncompleted: complete)
    })
   }
   
  }
  
 }
// 該方法模仿uipageviewcontroller,切換到某一個(gè)controller
func setviewcontroller(viewcontroller: uiviewcontroller, direction: translationcontrollernavigationdirection, animated: bool, completionhandler: ((bool) -> void)?) -> void {
  if animated == false {
   // 直接添加child controller ,略
  }else {
   let oldcontroller = self.childviewcontrollers.first
   self.addcontroller(controller: viewcontroller)
   
   var newvcendtransform: cgaffinetransform
   var oldvcendtransform: cgaffinetransform
   viewcontroller.view.transform = .identity
   if direction == .left {
    viewcontroller.view.transform = cgaffinetransform(translationx: screenwidth, y: 0)
    newvcendtransform = .identity
    oldcontroller?.view.transform = .identity
    oldvcendtransform = cgaffinetransform(translationx: -screenwidth, y: 0)
   }else {
    viewcontroller.view.transform = cgaffinetransform(translationx: -screenwidth, y: 0)
    newvcendtransform = .identity
    oldcontroller?.view.transform = .identity
    oldvcendtransform = cgaffinetransform(translationx: screenwidth, y: 0)
   }
   
   uiview.animate(withduration: animationduration, animations: {
    oldcontroller?.view.transform = oldvcendtransform
    viewcontroller.view.transform = newvcendtransform
   }, completion: { (complete) in
    if complete {
     self.removecontroller(controller: oldcontroller!)
    }
    if completionhandler != nil {
     completionhandler!(complete)
    }
    
   })
  }
 }

最終效果像這樣:

ios電子書翻頁(yè)效果代碼詳解

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本特黄一级大片 | 我年轻漂亮的继坶2中字在线播放 | 精品日韩欧美一区二区三区 | 500福利第一巨人导航 | 美女脱得一二净无内裤全身的照片 | 亚洲 欧美 清纯 校园 另类 | 99久久一区二区精品 | 亚洲日本va午夜中文字幕 | 日本最大的黄色网站 | 丰满岳乱妇在线观看视频国产 | 免费看日产一区二区三区 | 99精品久久99久久久久久 | 国产麻豆91欧美一区二区 | 好女孩韩剧免费观看 | 色操网 | 国产成人精品一区二三区2022 | 97影院伦理| 精品破处| 亚洲狠狠婷婷综合久久蜜桃 | 国产美女下面流出白浆视频 | 免费看视频 | 国产午夜亚洲精品一区网站 | 小伙无套内射老女人 | 欧美视频一区二区三区四区 | 99国产精品热久久久久久夜夜嗨 | 美女曰逼视频 | 欧美一区二区日韩一区二区 | 毛片网站大全 | 亚洲第一人黄所 | a人片| 日本精品一二三区 | 精品久久久噜噜噜久久7 | 国产馆精品推荐在线观看 | 亚洲精品视频导航 | 久青草国产在视频在线观看 | 特黄特色大片免费视频大全 | gaychinese男男2022| 夫妻性生活在线 | 手机在线观看精品国产片 | 无码人妻视频又大又粗欧美 | 青青视频国产依人在线 |