Có thể lật trang theo chương trình trong UIPageViewControll không?


Câu trả lời:


235

Có, nó có thể với phương thức:

- (void)setViewControllers:(NSArray *)viewControllers 
                 direction:(UIPageViewControllerNavigationDirection)direction 
                  animated:(BOOL)animated 
                completion:(void (^)(BOOL finished))completion;`

Đó là phương pháp tương tự được sử dụng để thiết lập bộ điều khiển xem đầu tiên trên trang. Tương tự, bạn có thể sử dụng nó để đi đến các trang khác.

Tự hỏi tại sao viewControllerslà một mảng, và không phải là một bộ điều khiển xem đơn?

Đó là bởi vì bộ điều khiển xem trang có thể có "cột sống" (như trong iBooks), hiển thị 2 trang nội dung cùng một lúc. Nếu bạn hiển thị 1 trang nội dung tại một thời điểm, thì chỉ cần chuyển vào một mảng 1 phần tử.

Một ví dụ trong Swift:

pageContainer.setViewControllers([displayThisViewController], direction: .Forward, animated: true, completion: nil)

2
Bây giờ NDA đã lên, điều này có thể được mở rộng thêm một chút không? Có thể là một mẫu mã.
SpaceTrucker

11
Tôi nghĩ rằng cuối cùng tôi cũng hiểu điều này: UIPageViewControll không thực sự quan tâm đến trang hiện tại. Khi bạn gọi setViewControllers, có thể thấy rằng bạn đang điều hướng hoạt hình ra khỏi bộ điều khiển chế độ xem hiện tại, nhưng nó không thực sự tìm kiếm một trang.
Amy

3
ví dụ: [self setViewControllers: @ [vcToMoveTo] direction: UIPageViewControllNavlationDirectionForward hoạt hình: CÓ hoàn thành: nil]; // trong đó vcToMoveTo là một UIViewContoder
finneycanhelp

1
Nếu bạn muốn tiếp tục sử dụng UIPageControl, thì bạn có thể muốn: self.cienIndex = viewControllToMoveTo của chỉ mục sau đó để trình bày IndexForPageViewControll trả về self.cien Index
brendan

3
Kiểm tra stackoverflow.com/questions/22554877/ cấp nếu bạn cũng cần cập nhật hiển thị chỉ báo trang
Protongun

37

Vì tôi cũng cần điều này, tôi sẽ đi sâu vào chi tiết hơn về cách thực hiện.

Lưu ý: Tôi giả sử bạn đã sử dụng mẫu biểu mẫu tiêu chuẩn để tạo UIPageViewControllercấu trúc của mình - có cả modelViewControllerdataViewControllerđược tạo khi bạn gọi nó. Nếu bạn không hiểu những gì tôi đã viết - hãy quay lại và tạo một dự án mới sử dụngUIPageViewController làm cơ sở. Bạn sẽ hiểu.

Vì vậy, cần phải lật sang một trang cụ thể liên quan đến việc thiết lập các phần khác nhau của phương pháp được liệt kê ở trên. Đối với bài tập này, tôi giả định rằng đó là chế độ xem phong cảnh với hai chế độ xem hiển thị. Ngoài ra, tôi đã triển khai điều này như một IBAction để nó có thể được thực hiện từ một lần nhấn nút hoặc không - thật dễ dàng để làm cho nó chọn cuộc gọi và chuyển vào các mục cần thiết.

Vì vậy, trong ví dụ này, bạn cần hai bộ điều khiển chế độ xem sẽ được hiển thị - và tùy chọn, cho dù bạn đang đi tiếp trong cuốn sách hay ngược lại.

Lưu ý rằng tôi chỉ mã hóa cứng ở đâu để đến trang 4 & 5 và sử dụng phiếu chuyển tiếp. Từ đây bạn có thể thấy rằng tất cả những gì bạn cần làm là chuyển vào các biến sẽ giúp bạn có được các mục này ...

-(IBAction) flipToPage:(id)sender {

    // Grab the viewControllers at position 4 & 5 - note, your model is responsible for providing these.  
    // Technically, you could have them pre-made and passed in as an array containing the two items...

    DataViewController *firstViewController = [self.modelController viewControllerAtIndex:4 storyboard:self.storyboard];
    DataViewController *secondViewController = [self.modelController viewControllerAtIndex:5 storyboard:self.storyboard];

    //  Set up the array that holds these guys...

    NSArray *viewControllers = nil;

    viewControllers = [NSArray arrayWithObjects:firstViewController, secondViewController, nil];

    //  Now, tell the pageViewContoller to accept these guys and do the forward turn of the page.
    //  Again, forward is subjective - you could go backward.  Animation is optional but it's 
    //  a nice effect for your audience.

      [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];

    //  Voila' - c'est fin!  

}

2
Tôi có cùng yêu cầu để chuyển đến một trang cụ thể. Nhưng đoạn mã trên dường như không hoạt động với tôi. Tôi đang làm gì sai? Tôi có 19 trang.
GaneshT

Chúng ta có thể sử dụng đoạn mã này khi cung cấp bộ điều khiển xem thông qua một đối tượng nguồn dữ liệu không?
Jens Kohl

20
Thật là một lớp học kỳ lạ được thực hiện kém, Apple.
devios1

29

Đây là một ví dụ mã khác cho một khung nhìn phân trang duy nhất. Việc thực hiện cho viewControllAtIndex được bỏ qua ở đây, nó sẽ trả về trình điều khiển khung nhìn chính xác cho chỉ mục đã cho.

- (void)changePage:(UIPageViewControllerNavigationDirection)direction {
    NSUInteger pageIndex = ((FooViewController *) [_pageViewController.viewControllers objectAtIndex:0]).pageIndex;

    if (direction == UIPageViewControllerNavigationDirectionForward) {
        pageIndex++;
    }
    else {
        pageIndex--;
    }

    FooViewController *viewController = [self viewControllerAtIndex:pageIndex];

    if (viewController == nil) {
        return;
    }

    [_pageViewController setViewControllers:@[viewController]
                                  direction:direction
                                   animated:YES
                                 completion:nil];
}

Các trang có thể được thay đổi bằng cách gọi

[self changePage:UIPageViewControllerNavigationDirectionReverse];
[self changePage:UIPageViewControllerNavigationDirectionForward];

Nhưng kiểm soát chỉ mục trang không được cập nhật. Làm thế nào để làm điều đó?
thatzprem

1
Câu trả lời này phù hợp với tôi - tuy nhiên lưu ý rằng nếu bạn đang dựa vào các phương thức ủy nhiệm "didFinishAnimating" của UIPageViewControll, chúng sẽ không bị loại bỏ. Thay vào đó, hãy chuyển mã của bạn từ didFinishAnimating sang một phương thức riêng và gọi phương thức đó từ khối hoàn thành trên phương thức setViewControllers.
DiscDev

1
@thatzprem Nếu bạn muốn tiếp tục sử dụng UIPageControl, sau đó bạn có thể muốn: self.currentIndex = viewControllerToMoveTo của chỉ số sau đó cho presentationIndexForPageViewController trở self.currentIndex
Brendan

@thatzprem nói đúng. Mỗi lần nó sẽ vào cùng một trang. Ví dụ: nếu chúng tôi có 3 trang, thì mỗi lần nó sẽ chỉ đến trang thứ 2.
Tushar Lathiya

18

Tôi hoàn toàn có thể thiếu một cái gì đó ở đây, nhưng giải pháp này có vẻ đơn giản hơn nhiều so với nhiều đề xuất khác.

extension UIPageViewController {
    func goToNextPage(animated: Bool = true, completion: ((Bool) -> Void)? = nil) {
        if let currentViewController = viewControllers?[0] {
            if let nextPage = dataSource?.pageViewController(self, viewControllerAfter: currentViewController) {
                setViewControllers([nextPage], direction: .forward, animated: animated, completion: completion)
            }
        }
    }
}

1
Hoạt động tuyệt vời! Chỉ cần thay đổi chỉ số trang bằng cách nào đó.
TruMan1

Thực sự hữu ích! Vui lòng cung cấp cho chúng tôi một chức năng cho goToFirstPage.
Mamta

Mỗi lần nó sẽ vào cùng một trang. Ví dụ: nếu chúng tôi có 3 trang, thì mỗi lần nó sẽ chỉ đến trang thứ 2.
Tushar Lathiya

15

Mã này đã làm việc tốt cho tôi, cảm ơn.

Đây là những gì tôi đã làm với nó. Một số phương pháp để tiến lên hoặc lùi lại và một phương pháp để đi trực tiếp đến một trang cụ thể. Nó cho một tài liệu 6 trang trong chế độ xem dọc. Nó sẽ hoạt động tốt nếu bạn dán nó vào việc triển khai RootContoder của mẫu pageViewControll.

-(IBAction)pageGoto:(id)sender {

    //get page to go to
    NSUInteger pageToGoTo = 4;

    //get current index of current page
    DataViewController *theCurrentViewController = [self.pageViewController.viewControllers   objectAtIndex:0];
    NSUInteger retreivedIndex = [self.modelController indexOfViewController:theCurrentViewController];

    //get the page(s) to go to
    DataViewController *targetPageViewController = [self.modelController viewControllerAtIndex:(pageToGoTo - 1) storyboard:self.storyboard];

    DataViewController *secondPageViewController = [self.modelController viewControllerAtIndex:(pageToGoTo) storyboard:self.storyboard];

    //put it(or them if in landscape view) in an array
    NSArray *theViewControllers = nil;    
    theViewControllers = [NSArray arrayWithObjects:targetPageViewController, secondPageViewController, nil];


    //check which direction to animate page turn then turn page accordingly
    if (retreivedIndex < (pageToGoTo - 1) && retreivedIndex != (pageToGoTo - 1)){
        [self.pageViewController setViewControllers:theViewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
    }

    if (retreivedIndex > (pageToGoTo - 1) && retreivedIndex != (pageToGoTo - 1)){
        [self.pageViewController setViewControllers:theViewControllers direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:NULL];
    }

}


-(IBAction)pageFoward:(id)sender {

    //get current index of current page
    DataViewController *theCurrentViewController = [self.pageViewController.viewControllers objectAtIndex:0];
    NSUInteger retreivedIndex = [self.modelController indexOfViewController:theCurrentViewController];

    //check that current page isn't first page
    if (retreivedIndex < 5){

        //get the page to go to
        DataViewController *targetPageViewController = [self.modelController viewControllerAtIndex:(retreivedIndex + 1) storyboard:self.storyboard];

        //put it(or them if in landscape view) in an array
        NSArray *theViewControllers = nil;    
        theViewControllers = [NSArray arrayWithObjects:targetPageViewController, nil];

        //add page view
        [self.pageViewController setViewControllers:theViewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];

    }

}


-(IBAction)pageBack:(id)sender {


    //get current index of current page
    DataViewController *theCurrentViewController = [self.pageViewController.viewControllers objectAtIndex:0];
    NSUInteger retreivedIndex = [self.modelController indexOfViewController:theCurrentViewController];

    //check that current page isn't first page
    if (retreivedIndex > 0){

    //get the page to go to
    DataViewController *targetPageViewController = [self.modelController viewControllerAtIndex:(retreivedIndex - 1) storyboard:self.storyboard];

    //put it(or them if in landscape view) in an array
    NSArray *theViewControllers = nil;    
    theViewControllers = [NSArray arrayWithObjects:targetPageViewController, nil];

    //add page view
    [self.pageViewController setViewControllers:theViewControllers direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:NULL];

    }

}

tôi muốn sử dụng nó cho chế độ nằm ngang nơi có hai trang. Làm thế nào để sử dụng nó ở đó. bạn có thể vui lòng hướng dẫn.
iPhone lập trình

9

Swift 4:

Tôi cần phải đi đến bộ điều khiển tiếp theo khi tôi chạm vào bộ điều khiển xem pagecontler tiếp theo và cũng cập nhật chỉ mục pageControl, vì vậy đây là giải pháp tốt nhất và đơn giản nhất đối với tôi :

let pageController = self.parent as! PageViewController

pageController.setViewControllers([parentVC.orderedViewControllers[1]], direction: .forward, animated: true, completion: nil)

pageController.pageControl.currentPage = 1

5

Còn việc sử dụng các phương thức từ dataSource thì sao?

UIViewController *controller = [pageViewController.dataSource pageViewController:self.pageViewController viewControllerAfterViewController:pageViewController.viewControllers.firstObject];
[pageViewController setViewControllers:@[controller] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];

Tương tự cho lạc hậu.


3

Trong Swift :

import UIKit

extension HomeViewController {

    // MARK: - Carousel management.

    func startTimerForMovingCarousel(let numberOfSecondsBetweenFiringsOfTheTimer: NSTimeInterval) {
        if (self.timerForMovingCarousel == nil) {
            self.timerForMovingCarousel = NSTimer.scheduledTimerWithTimeInterval(numberOfSecondsBetweenFiringsOfTheTimer,
                                                                            target: self,
                                                                            selector: "moveCarousel",
                                                                            userInfo: nil,
                                                                            repeats: true)
        }
    }

    func moveCarousel() {
        println("I move the carousel.")

        let currentContentViewControllerDisplayed = self.pageViewController!.viewControllers[0] as! ContentViewController

        var index: Int = currentContentViewControllerDisplayed.index

        if index == self.arrayViewControllers.count - 1 {
            index = 0
        } else {
            ++index
        }

        let contentViewControllerToDisplay = self.arrayViewControllers[index] as! ContentViewController

        self.pageViewController.setViewControllers([contentViewControllerToDisplay],
                                                    direction: UIPageViewControllerNavigationDirection.Forward,
                                                    animated: true,
                                                    completion: nil)

        self.pageControl.currentPage = contentViewControllerToDisplay.index
    }

    func invalidateTimerForMovingCarousel() {
        if (self.timerForMovingCarousel != nil) {
            self.timerForMovingCarousel.invalidate()
            self.timerForMovingCarousel = nil
        }
    }

}

1
Bạn có thể vui lòng cho tôi ví dụ đầy đủ cho việc này. Vì tôi đang làm một số việc như thế này. Làm thế nào để sử dụng phần mở rộng này với mã của tôi. Nếu bạn muốn tôi có thể gửi cho bạn mã.
Saty

2

Tuy nhiên, bằng cách sử dụng lệnh gọi phương thức 'self.pageViewControll setViewControllers này sẽ không gọi' viewDidDissapear 'trên viewContoder cho trang đã bị loại bỏ, trong khi đó, việc quay trang theo cách thủ công sẽ gọi viewDidDissapear trên trang bị quay đi. Tôi tin rằng đây là nguyên nhân của vụ tai nạn của tôi

"Số lượng bộ điều khiển xem được cung cấp (0) không khớp với số lượng yêu cầu (1) cho quá trình chuyển đổi được yêu cầu"


hãy thử sử dụng: - pageViewControll: didFinishAnimating: trướcViewControllers: quá trình hoàn thành:
Graham

2

Tôi cũng cần một nút để điều hướng sang trái trên PageViewControll, một nút sẽ thực hiện chính xác những gì bạn mong đợi từ chuyển động vuốt.

Vì tôi đã có sẵn một vài quy tắc bên trong " pageViewControll: viewControllB BeforeViewControll " để xử lý điều hướng vuốt tự nhiên, tôi muốn nút này sử dụng lại tất cả mã đó và đơn giản là không thể sử dụng các chỉ mục cụ thể để truy cập các trang như trước đây câu trả lời đã làm. Vì vậy, tôi đã phải thực hiện một giải pháp thay thế.

Xin lưu ý rằng đoạn mã sau dành cho Trình điều khiển Chế độ xem Trang là một thuộc tính bên trong ViewContoder tùy chỉnh của tôi và có cột sống được đặt ở giữa.

Đây là đoạn mã tôi đã viết cho nút Điều hướng bên trái của mình:

- (IBAction)btnNavigateLeft_Click:(id)sender {

    // Calling the PageViewController to obtain the current left page
    UIViewController *currentLeftPage = [_pageController.viewControllers objectAtIndex:0];

    // Creating future pages to be displayed
    NSArray *newDisplayedPages = nil;
    UIViewController *newRightPage = nil;
    UIViewController *newLeftPage = nil;

    // Calling the delegate to obtain previous pages
    // My "pageViewController:viewControllerBeforeViewController" method returns nil if there is no such page (first page of the book).
    newRightPage = [self pageViewController:_pageController viewControllerBeforeViewController:currentLeftPage];
    if (newRightPage) {
        newLeftPage = [self pageViewController:_pageController viewControllerBeforeViewController:newRightPage];
    }

    if (newLeftPage) {
        newDisplayedPages = [[NSArray alloc] initWithObjects:newLeftPage, newRightPage, nil];
    }

    // If there are two new pages to display, show them with animation.
    if (newDisplayedPages) {
        [_pageController setViewControllers:newDisplayedPages direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:nil];
    }
}

Bạn có thể làm một cái gì đó rất giống nhau để tạo một nút điều hướng bên phải từ đây.


2

Trong trường hợp nếu KIỂM SOÁT TRANG để chỉ ra trang hiện tại là O && Bạn muốn các trang điều hướng qua cuộn & cũng bằng cách nhấp vào các nút tùy chỉnh trong Trang ViewContoder, bên dưới có thể hữu ích.

//Set Delegate & Data Source for PageView controller [Say in View Did Load]
   self.pageViewController.dataSource = self;
   self.pageViewController.delegate = self;

// Delegates called viewControllerBeforeViewController when User Scroll to previous page 

 - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController{

    [_nextBtn setTitle:@"Next" forState:UIControlStateNormal];

    NSUInteger index = ((PageContentViewController*) viewController).pageIndex;

    if (index == NSNotFound){
        return nil;
    }else if (index > 0){
        index--;
    }else{
        return nil;
    }        
    return [self viewControllerAtIndex:index];        
}

// Đại biểu được gọi là viewContoderAfterViewControll khi Người dùng cuộn sang trang tiếp theo

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController{

    NSUInteger index = ((PageContentViewController*) viewController).pageIndex;

if (index == NSNotFound){
    return nil;
}else if (index < 3){
    index++;
}else{
    return nil;
}
return [self viewControllerAtIndex:index];}

//Delegate called while transition of pages. The need to apply logic in this delegate is to maintain the index of current page.

 - (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers{ 

buttonIndex = (int)((PageContentViewController*) pendingViewControllers.firstObject).pageIndex;

}

-(void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed{    
if (buttonIndex == 0){
    _backButton.hidden = true;
}else if (buttonIndex == [self.pageImages count] - 1){
    _backButton.hidden = false;
    [_nextBtn setTitle:@"Begin" forState:UIControlStateNormal];
}else{
    _backButton.hidden = false;
}

}

// Logic của nút tùy chỉnh (Trước & tiếp theo)

-(void)backBtnClicked:(id)sender{
    if (buttonIndex > 0){
buttonIndex -= 1;
    }
    if (buttonIndex < 1) {
        _backButton.hidden = YES;
    }
    if (buttonIndex >=0) {
         [_nextBtn setTitle:@"Next" forState:UIControlStateNormal];
        PageContentViewController *startingViewController = [self viewControllerAtIndex:buttonIndex];
        NSArray *viewControllers = @[startingViewController];
        [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
    }

}

-(void)nextBtnClicked:(id)sender{
if (buttonIndex < 3){
buttonIndex += 1;
}
if(buttonIndex == _pageImages.count){
   //Navigate Outside Pageview controller        
}else{        
    if (buttonIndex ==3) {

        [_nextBtn setTitle:@"Begin" forState:UIControlStateNormal];
    }
    _backButton.hidden = NO;

    PageContentViewController *startingViewController = [self viewControllerAtIndex:buttonIndex];
    NSArray *viewControllers = @[startingViewController];
    [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
}

}

//BUTTON INDEX & MAX COUNT
-(NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController{
    return [self.pageImages count];}

-(NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController{
    return  buttonIndex;}

Bạn đã đăng câu trả lời gần như chính xác cho bốn câu hỏi. Nếu bạn nghĩ rằng một trong số chúng là bản sao của cái kia, bạn nên đánh dấu chúng như vậy (và không đăng cùng một câu trả lời nhiều lần).
Jaap

Vì vậy, tôi có thể gửi liên kết của câu hỏi này hơn câu hỏi tương tự khác nhưng giải pháp là như nhau.
Yogesh Lolusare

1
Tôi không có ý phán xét hay bất cứ điều gì, nhưng định dạng mã của bạn có vẻ rất khó chịu với tôi.
Lukas Petr

1
Phải @Lukas, tôi sẽ định dạng nó ngay bây giờ. Cảm ơn
Yogesh Lolusare

2
- (void)moveToPage {

    NSUInteger pageIndex = ((ContentViewController *) [self.pageViewController.viewControllers objectAtIndex:0]).pageIndex;

    pageIndex++;

    ContentViewController *viewController = [self viewControllerAtIndex:pageIndex];

if (viewController == nil) {
        return;
    }
    [self.pageViewController setViewControllers:@[viewController] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];

}

// bây giờ gọi phương thức này

[tự di chuyển ToPage];

Tôi hy vọng nó hoạt động :)


1

Đối với một trang, tôi chỉ chỉnh sửa câu trả lời của @Jack Humphries

-(void)viewDidLoad
{
  counter = 0;
}
-(IBAction)buttonClick:(id)sender
{
  counter++;
  DataViewController *secondVC = [self.modelController viewControllerAtIndex:counter storyboard:self.storyboard];
  NSArray *viewControllers = nil;          
  viewControllers = [NSArray arrayWithObjects:secondVC, nil];          
  [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
}

0

Như @samwize đã chỉ ra, cách phân trang là sử dụng

setViewControllers:array

Đây là cách tôi đã làm: Tôi có nguồn dữ liệu của mình và đại biểu riêng biệt. Bạn có thể gọi phương thức này và chỉ thay đổi giao diện "tiếp theo". Trước đây bạn phải áp dụng quy tắc phân trang. Đó là, bạn phải kiểm tra hướng và bộ điều khiển tiếp theo. Nếu bạn sử dụng phương pháp đó với nguồn dữ liệu tùy chỉnh của mình, thì bộ điều khiển mà bạn đang hiển thị sẽ không thay đổi (vì bạn sẽ sử dụng một mảng tùy chỉnh trên lớp con NSObject).

Sử dụng nguồn dữ liệu của riêng bạn, phương pháp chỉ đặt một chế độ xem mới (với hướng cụ thể). Vì bạn vẫn sẽ kiểm soát các trang sẽ hiển thị khi vuốt bình thường.


0

Tôi đang làm việc với nó từ hôm qua và cuối cùng tôi đã làm được. Tôi không thể sử dụng mẫu tiêu chuẩn hoàn toàn, bởi vì tôi có ba khác biệt viewControllers khi xem xét trẻ em:

1 - rootViewController;
2 - model;
3 - viewControllers
3.1 - VC1;
3.2 - VC2;
3.3 - VC3.
Note: all of VCs has Storyboard ID.

Tôi chỉ cần một nút kích hoạt trong một VC đầu tiên, vì vậy tôi đã thêm một thuộc tính cho pageViewControll và model:

#import <UIKit/UIKit.h>
#import "Model.h"

@interface VC1 : UIViewController

@property (nonatomic, strong) UIPageViewController *thePageViewController;
@property (nonatomic, strong) SeuTimePagesModel *theModel;

@end

Tôi viết lại phương thức init của mô hình để truyền bảng phân cảnh và pageViewControll làm tham số, vì vậy tôi có thể đặt chúng vào VC1 của mình:

- (id)initWithStoryboard:(UIStoryboard *)storyboard
   andPageViewController:(UIPageViewController *)controller
{
    if (self = [super init])
    {
        VC1 *vc1 = [storyboard instantiateViewControllerWithIdentifier:@"VC1"];
        vc1.pageViewController = controller;
        vc1.model = self;

        VC2 *vc2 = [storyboard instantiateViewControllerWithIdentifier:@"VC2"];
        VC3 *vc3 = [storyboard instantiateViewControllerWithIdentifier:@"VC3"];
        self.pageData = [[NSArray alloc] initWithObjects:vc1, vc2, vc3, nil];
    }

    return self;
}

Cuối cùng, tôi đã thêm một IBAction trong vc1 của mình để kích hoạt phương thức pageViewControll setViewControllers: direction: animation: xong ::

- (IBAction)go:(id)sender
{
    VC2 *vc2 = [_model.pages objectAtIndex:1];
    NSArray *viewControllers = @[vc2];
    [_pageViewController setViewControllers:viewControllers
                                  direction:UIPageViewControllerNavigationDirectionForward
                                   animated:YES
                                 completion:nil];
}

Lưu ý Tôi không cần tìm các chỉ mục VC, nút của tôi đưa tôi đến VC thứ hai của tôi, nhưng không khó để lấy tất cả các chỉ mục và theo dõi các lần xem xét con của bạn:

- (IBAction)selecionaSeuTime:(id)sender
{
    NSUInteger index = [_model.pages indexOfObject:self];
    index++;

    VC2 *vc2 = [_model.pages objectAtIndex:1];
    NSArray *viewControllers = @[vc2];
    [_pageViewController setViewControllers:viewControllers
                                  direction:UIPageViewControllerNavigationDirectionForward
                                   animated:YES
                                 completion:nil];
}

Tôi hy vọng nó sẽ giúp bạn!


0

Đây là một giải pháp sử dụng các phương thức UIPageViewControllDataSource :

Mã theo dõi bộ điều khiển xem hiển thị hiện tại trong UIPageViewCont kiểm soát .

...
@property (nonatomic, strong) UIViewController *currentViewController;
@property (nonatomic, strong) UIViewController *nextViewController;
...

Đầu tiên khởi tạo currentViewCont Bộ điều khiển cho bộ điều khiển xem ban đầu được đặt cho UIPageViewContaptor .

- (void) viewDidLoad {
    [super viewDidLoad];
    ...
    self.currentViewController = self.viewControllers[0];
    ...
    [self.pageViewController setViewControllers: @[self.currentViewController] direction: dir animated: YES completion: nil];
}

Sau đó theo dõi currentViewController trong UIPageViewControllerDelegate phương pháp: pageViewController: willTransitionToViewControllers:pageViewController: didFinishAnimating: previousViewControllers: transitionCompleted: .


- (nullable UIViewController *) pageViewController: (UIPageViewController *) pageViewController viewControllerBeforeViewController: (UIViewController *) viewController {
    NSInteger idx = [self.viewControllers indexOfObject: viewController];
    if (idx > 0) {
        return self.viewControllers[idx - 1];
    } else {
        return nil;
    }
}

- (nullable UIViewController *) pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController: (UIViewController *) viewController {
    NSInteger idx = [self.viewControllers indexOfObject: viewController];
    if (idx == NSNotFound) {
        return nil;
    } else {
        if (idx + 1 < self.viewControllers.count) {
            return self.viewControllers[idx + 1];
        } else {
            return nil;
        }
    }
}

- (void) pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray<UIViewController *> *)pendingViewControllers {
    self.nextViewController = [pendingViewControllers firstObject];
}

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray<UIViewController *> *)previousViewControllers transitionCompleted:(BOOL)completed {
    if (completed) {
        self.currentViewController = self.nextViewController;
    }
}

Cuối cùng, trong phương pháp của sự lựa chọn của bạn (trong ví dụ dưới đây của nó - (IBAction) onNext: (id) người gửi ), bạn có thể lập trình chuyển sang bộ điều khiển tiếp theo hoặc trước đó sử dụng UIPageViewControllerDataSouce phương pháp pageViewController: viewControllerBeforeViewController: , pageViewController: viewControllerAfterViewController: để có được bộ điều khiển xem tiếp theo hoặc trước và điều hướng đến nó bằng cách gọi [self.pageViewControll setViewControllers: @ [vc] direction: UIPageViewControllNavlationDirectionForward hoạt hình: YES xong: nil];


- (void) onNext {
    UIViewController *vc = [self pageViewController: self.tutorialViewController viewControllerAfterViewController: self.currentViewController];
    if (vc != nil) {
        self.currentViewController = vc;
        [self.tutorialViewController setViewControllers: @[vc] direction: UIPageViewControllerNavigationDirectionForward animated: YES completion: nil];
    }
}

Một lời giải thích chi tiết sẽ rất hữu ích.
Taslim Oseni

@TaslimOseni cảm ơn vì đã chỉ ra rằng ví dụ này không đủ rõ ràng. Tôi đã thêm mô tả về cách thức hoạt động của nó, xin vui lòng cho tôi biết nếu nó cần giải thích thêm.
pconor

0

Vì ViewControllers được nhúng trong PageViewControll, tất cả những gì bạn phải làm là:

  • Truy xuất bộ điều khiển xem cha mẹ và chọn làm lớp có liên quan của bạn.
  • Sử dụng thuộc tính nguồn dữ liệu cha mẹ đó để có được ViewContoder tiếp theo.
  • Sử dụng phương thức SetParentViewControllers để đặt và chuyển sang trang tiếp theo.

Ví dụ trong Xamarin, nhưng có chức năng tương tự Swift, v.v. Mã sau sẽ có trong Nút Nhấp vào ủy nhiệm trong một trong các ViewControllers được hiển thị dưới dạng trang:

var parent = ParentViewController as WelcomePageViewController;
var next = parent.DataSource.GetNextViewController(parent, this);

parent.SetViewControllers(new UIViewController[] { next }, UIPageViewControllerNavigationDirection.Forward, true, null);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.