2013-02-26 26 views
6

我看了很多很多地方,還沒有找到一些很好的示例代碼,顯示如何在UIPageViewController中預加載「下一頁」頁面。 SO上有幾個答案,詳細介紹了一些理論方法(見this question),但還沒有人發佈一個工作示例。預加載UIPageViewController中的下一頁

在我的應用程序的工作流程中,我顯示每個屏幕1頁,並且我希望預加載「下一個」屏幕,因爲實際上,滑動到下一頁可能非常緩慢,有時需要2次滑動(如果你刷得太快),以便下一頁被渲染和顯示。這提供了糟糕的用戶體驗。我並不在乎預先加載「之前」或其他任何屏幕,因爲典型的工作流程是用戶在屏幕上停留一段時間,然後再轉到下一個屏幕(向右)。我正在使用幻燈片動畫(不是蜷縮起來)。我以編程方式創建所有視圖,完全不使用IB。

我試圖將一些UIViewControllers存儲在一個NSMutableArray中,並從那裏加載控制器,但它很難做到正確工作,似乎並沒有加快速度。必須有一個很好的方法來做到這一點。

任何幫助,非常感謝。

+1

您是否找到了解決方案?我有同樣的問題,滑到下一個視圖控制器時會顯着滯後。 – mattsson 2014-02-20 09:23:20

+0

排序,但答案是非常具體的我的實施。正如我在發佈這個問題後與UIPageViewController合作過很多,我發現這是一個非常棘手的問題。基本上,我的問題更多的是與查詢數據庫查詢正確的數據有關,這會減慢每個頁面的速度。我能夠通過預先計算數據庫中的數據,並使用自動佈局繪製視圖而不是混亂框架來優化頁面輪換 - 這對我們有很大的幫助。其次我有很多的圖像顯示,所以我直接在「主」視圖控制器(滑動的父)將它們存儲在一個NSMutableArray中。 – DiscDev 2014-02-20 15:41:46

+0

我的「解決方案」最終成爲......不斷等待蘋果公司推出更快的手機......哈哈哈。在iPhone 6/6s上,不再有延遲。我優化了一些數據庫抓取代碼,當頁面控制器第一次創建時會發生一次並且幫助了很多,但主要的速度改進來自更快的處理器和更多的RAM,並且逐步取消對iPhone 4/4s的支持=) – DiscDev 2015-10-12 19:05:46

回答

0

您應該使用例如Instruments的Time Profiler來調試您的代碼。 這樣做,你會發現哪個對象具有最高的運行時間。 也許與UIPageViewController無關,但與頁面內的視圖無關。

2

我已經解決了我的情況有點破解。對於每個ContentView,我有一個UIScrollView內的UIImageView用於縮放。我的問題是,在啓動應用程序時,如果用戶在刷卡之前放大,在放大時進入下一頁將無法正常工作。我使用下面的代碼(Swift 1.2)來解決這個問題。正如我所說的那樣,這雖然有些破綻。

var layoutsubs = false 

override func viewDidLoad() { 
    super.viewDidLoad() 
    //Other code for implementing pageViewController omitted 

    //add pageViewController to main view 
    self.addChildViewController(pageViewController) 
    self.view.addSubview(pageViewController.view) 
    pageViewController.didMoveToParentViewController(self) 

    //Load to the viewController after the starting VC, then go back to the starting VC 
    var viewControllers = [afterVC] 
    pageViewController.setViewControllers(viewControllers as [AnyObject], direction: .Forward, animated: true, completion: nil) 
    viewControllers = [startingVC] 
    pageViewController.setViewControllers(viewControllers as [AnyObject], direction: .Reverse, animated: true, completion: nil) 
} 

override func viewWillLayoutSubviews() { 
    //Load the viewController before the starting VC then go back to the starting VC 
    //viewWillLayoutSubviews() is called multiple times, so do this only once 
    if !layoutsubs { 
     let startingVC = self.viewControllerAtIndex(imageIndex) as ContentViewController 
     let beforeVC = pageViewController(pageViewController, viewControllerBeforeViewController: startingVC) as! ContentViewController 

     var viewControllers = [beforeVC] 
     pageViewController.setViewControllers(viewControllers as [AnyObject], direction: .Reverse, animated: true, completion: nil) 
     viewControllers = [startingVC] 
     pageViewController.setViewControllers(viewControllers as [AnyObject], direction: .Forward, animated: true, completion: nil) 
     layoutsubs = true 
    } 
} 

本質上,我加載視圖控制器之前和之後的起始視圖控制器。我通過將每個設置爲VC來通過setViewControllers(_:direction:animated:completion:)see ref)來查看,然後返回到起始視圖控制器。爲什麼這是兩個不同的功能?那麼,如果你把它放在一個,那麼只有啓動VC旁邊的兩個視圖控制器中的一個會加載。這對某些情況可能是需要的,但我需要所有三個VC(加載之前,開始和之後)。

我不確定如果UIPageViewController已經被加載,這個方法可以工作多好。例如,如果您需要將頁面2加載離開正在查看的頁面,則需要幾次滑動。如果你把它放在willTransitionToViewControllers()中,它可能會跳過。

+0

如果你沒有固定數量的風險投資,這是如何工作的?有沒有一種方法可以一次預加載所有的數據,所以沒有問題?謝謝! – Jacob 2015-12-17 06:55:57

+0

@Jacob:如果您沒有固定數量的VC,那麼您首先必須檢查所選VC之前和之後是否存在VC。如果後面只有一個VC,則只能使用viewDidLoad()中的代碼,並且不會使用viewWillLayoutSubviews()。如果在它之前只有一個VC,你將使用'viewWillLayoutSubviews()'中的代碼,'viewWillLoad'中的所有內容都將從'// Load to viewController'開始。在這種情況下,您可以在'viewDidLoad()'中轉到前一個VC。我不確定如何預裝所有風險投資,對不起。 – 2016-01-04 08:22:10

+0

你好,你可以提供初始化pageViewController完整的代碼來完成它 – 2016-03-10 07:39:59