欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

ios電子書翻頁效果代碼詳解

 更新時間:2018年02月01日 11:33:32   投稿:laozhang  
這篇文章主要介紹了ios電子書翻頁效果代碼實現(xiàn)過程以及對應(yīng)的代碼講解,有需要的朋友參考下。

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

仿真翻頁

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

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

UIpageviewcontroller有一個屬性叫做isDoubleSided,默認(rèn)為yes,也就是內(nèi)容只會在單面(正面)顯示,設(shè)置為no后,內(nèi)容便可以正面和背面雙面顯示,這時每翻一頁,pageview的下面兩個回調(diào)會調(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
}

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

// 對輸入的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()
 }

效果像下面這樣

左右平滑翻頁

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

DUATranslationController

DUATranslationController并沒有采用Scrollview的方式實現(xiàn),而是基于controller容器,通過替換child controller來實現(xiàn),具體來說就是當(dāng)用戶點擊或者滑動時,判斷需要展示上一個頁面還是下一個頁面,然后模仿UIpageviewcontroller通過回調(diào)的方式索取controller,加入到controller容器中,并通過動畫的方式將新的controller平滑移動進(jìn)入屏幕,舊的controller同時移出,如下是單擊手勢代碼示例(滑動手勢涉及和用戶交互,邏輯更復(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 {
//   滑向上一個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 {
//   滑向下一個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,切換到某一個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)
    }
    
   })
  }
 }
 

最終效果像這樣:

相關(guān)文章

  • 淺談Xcode 開發(fā)工具 XCActionBar

    淺談Xcode 開發(fā)工具 XCActionBar

    本文主要給大家簡單講解了Xcode的開發(fā)工具 XCActionBar的介紹與使用方法,非常的全面實用,有需要的小伙伴可以參考下。
    2015-11-11
  • iOS 二維碼生成及掃碼詳解及實例代碼

    iOS 二維碼生成及掃碼詳解及實例代碼

    這篇文章主要介紹了iOS 二維碼生成及掃碼詳解及實例代碼的相關(guān)資料,需要的朋友可以參考下
    2016-12-12
  • iOS常用組件之高效切圓角的方法匯總

    iOS常用組件之高效切圓角的方法匯總

    最近在研究切圓角的方法,也找了下網(wǎng)上的資料,所以下面這篇文章主要給大家總結(jié)介紹了關(guān)于iOS常用組件之高效切圓角的一些方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • iOS開發(fā)中使用UIWebView 屏蔽 alert警告框

    iOS開發(fā)中使用UIWebView 屏蔽 alert警告框

    這篇文章主要介紹了iOS開發(fā)中使用UIWebView 屏蔽 alert警告框的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-11-11
  • iOS端React Native差異化增量更新的實現(xiàn)方法

    iOS端React Native差異化增量更新的實現(xiàn)方法

    這篇文章主要給大家介紹了關(guān)于iOS端React Native差異化增量更新的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-06-06
  • iOS如何將照片保存到相冊

    iOS如何將照片保存到相冊

    這篇文章主要為大家詳細(xì)介紹了iOS將照片保存到相冊的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • IOS開發(fā)Objective-C?Runtime使用示例詳解

    IOS開發(fā)Objective-C?Runtime使用示例詳解

    這篇文章主要為大家介紹了IOS開發(fā)Objective-C?Runtime使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • 簡單談?wù)刢/c++中#import、#include和@class的區(qū)別

    簡單談?wù)刢/c++中#import、#include和@class的區(qū)別

    對于#import,我想做過iOS開發(fā)的人應(yīng)該都不陌生。在開發(fā)過程中,當(dāng)我們需要聲明某一個類時,都需要去引用。而#imclude的話,在我們學(xué)習(xí)C時就已經(jīng)知道了,他的作用也是引用聲明的意思。在表面上他們的作用似乎都是一樣的。但是在具體功能實現(xiàn)方式上,還是有著很大的區(qū)別。
    2018-01-01
  • ios實現(xiàn)簡易隊列

    ios實現(xiàn)簡易隊列

    這篇文章主要為大家詳細(xì)介紹了ios實現(xiàn)簡易隊列,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • iOS 中weak的實現(xiàn)代碼示例

    iOS 中weak的實現(xiàn)代碼示例

    本篇文章主要介紹了iOS 中weak的實現(xiàn)代碼示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05

最新評論