2013-02-26 28 views
6

Tôi đã xem nhiều, nhiều địa điểm và chưa tìm thấy một số mã mẫu tốt cho thấy cách tải trước trang "tiếp theo" trong UIPageViewController. Có một vài câu trả lời trên SO chi tiết một số cách lý thuyết để làm điều đó (xem this question) nhưng chưa có ai đăng một ví dụ làm việc.Tải trước trang tiếp theo trong UIPageViewController

Trong quy trình làm việc của ứng dụng, tôi đang hiển thị 1 trang trên mỗi màn hình và tôi muốn tải trước màn hình "tiếp theo" vì việc vuốt sang trang tiếp theo có thể rất chậm, đôi khi yêu cầu 2 lần vuốt (nếu bạn vuốt quá nhanh) để trang tiếp theo hiển thị và hiển thị. Điều này mang lại trải nghiệm người dùng kém. Tôi không thực sự quan tâm đến việc tải trước "trước" hoặc bất kỳ màn hình nào khác vì quy trình làm việc điển hình sẽ là người dùng ở trên màn hình một lúc trước khi chuyển sang màn hình tiếp theo (ở bên phải). Tôi đang sử dụng hình động trang trình bày (không cuộn tròn). Tôi tạo ra tất cả các quan điểm một cách có lập trình và không sử dụng IB chút nào.

Tôi đã cố gắng lưu trữ một số UIViewControllers trong NSMutableArray và tải bộ điều khiển từ đó, nhưng thật khó để làm việc đúng và dường như không tăng tốc bất cứ thứ gì. Phải có cách tốt để làm điều này.

Bất kỳ trợ giúp nào được đánh giá cao.

+1

Bạn có tìm thấy giải pháp cho việc này không? Tôi có cùng một vấn đề, nhận được lag đáng chú ý khi swiping để điều khiển xem tiếp theo. – mattsson

+0

Sắp xếp, nhưng câu trả lời rất cụ thể cho việc triển khai của tôi. Như tôi đã làm việc với UIPageViewController rất nhiều kể từ khi đăng câu hỏi này, tôi đã tìm thấy nó là một chủ đề rất khó khăn. Về cơ bản, các vấn đề của tôi có liên quan nhiều hơn đến việc truy vấn DB cho đúng dữ liệu để hiển thị, điều này làm chậm mỗi trang xuống. Tôi đã có thể tối ưu hóa trang của mình bằng cách tính toán trước dữ liệu từ DB và vẽ chế độ xem của tôi bằng cách sử dụng Bố cục tự động thay vì làm rối tung khung hình - điều đó đã giúp ích rất nhiều. Thứ hai, tôi đã có rất nhiều hình ảnh để hiển thị, vì vậy tôi lưu trữ chúng trong một NSMutableArray trực tiếp trên bộ điều khiển xem "chính" (cha mẹ của swipe). – DiscDev

+0

"Giải pháp" của tôi đã kết thúc được ... tiếp tục chờ đợi Apple để đi ra với điện thoại nhanh hơn .... hahaha. Trên iPhone 6/6s, không còn tụt hậu nữa.Tôi được tối ưu hóa một số cơ sở dữ liệu lấy mã để xảy ra một lần khi bộ điều khiển trang đầu tiên được tạo ra và đã giúp rất nhiều, nhưng những cải tiến tốc độ chính đến từ bộ vi xử lý nhanh hơn và RAM hơn, và giảm dần hỗ trợ cho iPhone 4/4s =) – DiscDev

Trả lời

0

Bạn phải gỡ lỗi mã của mình, bằng cách sử dụng, ví dụ: Trình biên tập thời gian của các công cụ. Làm điều đó, bạn sẽ tìm thấy đối tượng nào có thời gian chạy cao nhất. Có thể nó không liên quan đến UIPageViewController nhưng để xem bên trong các trang.

2

Tôi đã giải quyết cho trường hợp của mình trong một chút hack. Đối với mỗi ContentView, tôi có một số UIImageView trong một số UIScrollView để thu phóng. Vấn đề của tôi là khi khởi động ứng dụng, nếu người dùng đã phóng to trước khi vuốt, chuyển sang trang tiếp theo trong khi phóng to sẽ không hoạt động tốt. Tôi sử dụng đoạn mã sau (Swift 1.2) để giải quyết vấn đề này. Như tôi đã nói, đó là một chút của một hack mặc dù.

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 
    } 
} 

Về cơ bản, tôi tải bộ điều khiển chế độ xem trước và sau bộ điều khiển chế độ xem khởi động. Tôi thực hiện việc này bằng cách đặt từng thiết bị vào VC để xem qua setViewControllers(_:direction:animated:completion:) (see ref), sau đó quay lại trình điều khiển chế độ xem bắt đầu. Tại sao điều này lại có hai chức năng khác nhau? Vâng, nếu bạn đặt tất cả trong một, chỉ một trong hai bộ điều khiển xem bên cạnh VC bắt đầu sẽ tải. Điều này có thể được mong muốn đối với một số trường hợp, nhưng tôi cần cả ba VC (trước, bắt đầu và sau) để tải.

Tôi không chắc phương pháp này hoạt động tốt như thế nào nếu UIPageViewController đã được tải. Ví dụ: nếu bạn cần tải trang 2 khỏi trang đang được xem, sau một vài lần vuốt. Nó có thể bỏ qua nếu bạn đặt nó trong willTransitionToViewControllers().

+0

Làm thế nào để làm việc này nếu bạn không có một số tiền cố định của VC? Có cách nào để tải trước tất cả chúng cùng một lúc để không có vấn đề gì không? Cảm ơn! – Jacob

+0

@Jacob: Nếu bạn không có số tiền cố định của VC, thì trước tiên bạn sẽ phải kiểm tra xem có VC trước và sau VC đã chọn hay không. Nếu chỉ có một VC sau nó, bạn sẽ chỉ sử dụng mã trong 'viewDidLoad()', và 'viewWillLayoutSubviews()' sẽ không được sử dụng. Nếu chỉ có một VC trước nó, bạn sẽ sử dụng mã trong 'viewWillLayoutSubviews()', và mọi thứ trong 'viewWillLoad' bắt đầu bằng' // Load to viewController sau VC khởi đầu ... 'chú thích sẽ bị loại bỏ. Bạn có thể đi đến VC trước đó trong 'viewDidLoad()' trong trường hợp này. Tôi không chắc chắn làm thế nào để tải trước tất cả các VC, xin lỗi. –

+0

xin chào bạn có thể cung cấp mã đầy đủ từ việc khởi tạo pageViewController để hoàn thành nó –

Các vấn đề liên quan