国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(tǒng) > iOS > 正文

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

2019-10-21 18:41:49
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

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

仿真翻頁(yè)

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

ios,電子書(shū)翻頁(yè)

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

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

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ì)很美觀了。
代碼示例

// 對(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,電子書(shū)翻頁(yè)

左右平滑翻頁(yè)

最初采用的是UIpageviewcontroller的另一種翻頁(yè)模式——滾動(dòng)模式。該模式蘋果在底層是用scrollView實(shí)現(xiàn)的。但這種模式在頁(yè)面切換時(shí)存在一些問(wèn)題,由于蘋果會(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ā)一些問(wèn)題,更詳細(xì)的說(shuō)明可以看這篇文章,因此決定自己寫一個(gè)翻頁(yè)控件

DUATranslationController

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

@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è)controllerfunc 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,電子書(shū)翻頁(yè)


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到IOS開(kāi)發(fā)頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 阳朔县| 东乡县| 驻马店市| 枣阳市| 乐陵市| 彭泽县| 庐江县| 康乐县| 吉隆县| 普兰店市| 长子县| 新化县| 德昌县| 福建省| 苍山县| 洞头县| 英山县| 巫溪县| 古浪县| 县级市| 八宿县| 醴陵市| 丹东市| 昭觉县| 文水县| 信阳市| 乡宁县| 广元市| 怀安县| 新建县| 冕宁县| 拉孜县| 安图县| 香河县| 临漳县| 丽江市| 双鸭山市| 甘肃省| 长治市| 出国| 辛集市|