เป็นไปได้หรือไม่ที่จะเปลี่ยนหน้าเป็นโปรแกรมใน UIPageViewController


161

เป็นไปได้UIPageViewControllerหรือไม่ที่จะเปลี่ยนหน้าในทางโปรแกรม


1
คุณช่วยกรุณาโพสต์โค้ดตัวอย่างสำหรับมันได้ไหม ขอบคุณสำหรับคุณ
iPhone โดยทางโปรแกรม

คำตอบ:


235

ใช่มันเป็นไปได้ด้วยวิธีการ:

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

นั่นคือวิธีการเดียวกับที่ใช้สำหรับการตั้งค่าตัวควบคุมมุมมองแรกบนหน้า ในทำนองเดียวกันคุณสามารถใช้มันเพื่อไปที่หน้าอื่น ๆ

สงสัยว่าทำไมviewControllersอาร์เรย์จึงไม่ใช่ตัวควบคุมมุมมองเดียว

เนื่องจากตัวควบคุมการดูหน้าอาจมี "กระดูกสันหลัง" (เช่นใน iBooks) โดยแสดงเนื้อหาได้ครั้งละ 2 หน้า หากคุณแสดงเนื้อหาครั้งละ 1 หน้าก็ให้ส่งต่อไปยังอาร์เรย์ 1 องค์ประกอบ

ตัวอย่างใน Swift:

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

2
ตอนนี้ NDA ขึ้นแล้วสิ่งนี้สามารถขยายได้อีกหรือไม่ อาจเป็นตัวอย่างรหัส
SpaceTrucker

11
ฉันคิดว่าในที่สุดฉันก็เข้าใจสิ่งนี้: UIPageViewController ไม่สนใจจริง ๆ ว่าหน้านี้เปิดอยู่ เมื่อคุณเรียกใช้ setViewControllers มันสามารถทำให้ดูเหมือนว่าคุณเคลื่อนไหวแบบการนำทางออกไปจากตัวควบคุมมุมมองปัจจุบัน แต่ไม่ได้ค้นหาหน้าเว็บจริงๆ
เอมี่

3
ตัวอย่าง: [ตนเอง setViewControllers: @ [vcToMoveTo] ทิศทาง: UIPageViewControllerNavigationDirectionForward ภาพเคลื่อนไหว: เสร็จสิ้นใช่: ไม่มี]; // โดยที่ vcToMoveTo เป็น UIViewController
finneycanhelp

1
หากคุณต้องการใช้ UIPageControl ต่อไปคุณอาจต้องการ: ดัชนีของ self.currentIndex = viewControllerToMoveTo จากนั้นสำหรับงานนำเสนอ InIndexForPageViewController ส่งกลับ self.currentIndex
เบรนแดน

3
ตรวจสอบstackoverflow.com/questions/22554877/…หากคุณจำเป็นต้องอัปเดตการแสดงผลตัวบ่งชี้หน้าด้วย
Protongun

37

เนื่องจากฉันต้องการสิ่งนี้เช่นกันฉันจะอธิบายรายละเอียดเพิ่มเติมเกี่ยวกับวิธีการทำเช่นนี้

หมายเหตุ: ฉันถือว่าคุณใช้แบบฟอร์มเทมเพลตมาตรฐานสำหรับการสร้างUIPageViewControllerโครงสร้างของคุณซึ่งมีทั้งmodelViewControllerและdataViewControllerสร้างเมื่อคุณเรียกใช้ หากคุณไม่เข้าใจสิ่งที่ฉันเขียน - ย้อนกลับไปและสร้างโครงการใหม่ที่ใช้UIPageViewControllerเป็นพื้นฐาน คุณจะเข้าใจแล้ว

ดังนั้นจำเป็นต้องพลิกไปยังหน้าเฉพาะเกี่ยวข้องกับการตั้งค่าชิ้นส่วนต่าง ๆ ของวิธีการที่กล่าวข้างต้น สำหรับแบบฝึกหัดนี้ฉันสมมติว่าเป็นมุมมองแนวนอนที่มีมุมมองสองมุมแสดง นอกจากนี้ฉันยังใช้สิ่งนี้เป็น IBAction เพื่อให้สามารถทำได้จากการกดปุ่มหรืออะไรก็ตาม - มันเป็นเรื่องง่ายที่จะเลือกตัวเลือกการโทรและส่งผ่านรายการที่ต้องการ

สำหรับตัวอย่างนี้คุณต้องมีตัวควบคุมมุมมองสองตัวที่จะแสดงขึ้น - และเป็นทางเลือกไม่ว่าคุณจะก้าวไปข้างหน้าในหนังสือหรือย้อนกลับ

โปรดทราบว่าฉันเพียงเขียนโค้ดยากที่จะไปที่หน้า 4 และ 5 และใช้สลิปไปข้างหน้า จากที่นี่คุณจะเห็นว่าสิ่งที่คุณต้องทำคือส่งผ่านตัวแปรที่จะช่วยให้คุณได้รับรายการเหล่านี้ ...

-(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
ฉันมีความต้องการเดียวกันเพื่อย้ายไปยังหน้าเฉพาะ แต่รหัสข้างต้นดูเหมือนจะไม่ทำงานสำหรับฉัน ผมทำอะไรผิดหรือเปล่า? ฉันมี 19 หน้า
GaneshT

เราสามารถใช้ข้อมูลโค้ดนี้เมื่อให้ตัวควบคุมมุมมองผ่านวัตถุแหล่งข้อมูลได้หรือไม่
Jens Kohl

20
ช่างเป็นแอปเปิ้ลที่มีคลาสที่มีคุณภาพต่ำ
devios1

29

นี่คืออีกตัวอย่างรหัสสำหรับมุมมองเพจเดียว มีการละเว้นการใช้งานสำหรับviewControllerAtIndexที่นี่ซึ่งควรส่งคืนตัวควบคุมมุมมองที่ถูกต้องสำหรับดัชนีที่กำหนด

- (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];
}

หน้าสามารถเปลี่ยนแปลงได้โดยการโทร

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

แต่ตัวควบคุมดัชนีหน้าไม่ได้รับการปรับปรุง ฉันจะทำอย่างไร
thatzprem

1
คำตอบนี้ใช้ได้สำหรับฉัน - โปรดทราบว่าหากคุณใช้วิธีการมอบหมาย "didFinishAnimating" ของ UIPageViewController พวกเขาจะไม่ถูกไล่ออก ให้ย้ายโค้ดของคุณจาก didFinishAnimating ไปที่เมธอดแยกต่างหากและเรียกเมธอดนั้นจากบล็อกการทำให้สมบูรณ์บนเมธอด setViewControllers
DiscDev

1
@thatzprem หากคุณต้องการใช้ UIPageControl ต่อไปคุณอาจต้องการ: ดัชนี self.currentIndex = viewControllerToMoveTo จากนั้นสำหรับงานนำเสนอIndexForPageViewController return self.currentIndex
Brendan

@thatzprem ถูกต้อง ทุกครั้งที่ไปที่หน้าเดียวกันตัวอย่างเช่นถ้าเรามี 3 หน้าแล้วทุกครั้งที่ไปที่หน้า 2 เท่านั้น
Tushar Lathiya

18

ฉันอาจจะพลาดอะไรบางอย่างที่นี่ แต่วิธีนี้ดูเหมือนง่ายกว่าที่คนอื่นเสนอ

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
ใช้งานได้ดี! เพียงแค่ต้องเปลี่ยนตัวบ่งชี้หน้าอย่างใด
TruMan1

มีประโยชน์จริง ๆ ! โปรดให้ฟังก์ชั่นสำหรับ goToFirstPage ด้วย
Mamta

ทุกครั้งที่ไปที่หน้าเดียวกันตัวอย่างเช่นถ้าเรามี 3 หน้าแล้วทุกครั้งที่ไปที่หน้า 2 เท่านั้น
Tushar Lathiya

15

รหัสนี้ทำงานได้ดีสำหรับฉันขอบคุณ

นี่คือสิ่งที่ฉันทำกับมัน วิธีการบางอย่างสำหรับการก้าวไปข้างหน้าหรือข้างหลังและวิธีหนึ่งสำหรับการไปยังหน้าใดหน้าหนึ่งโดยตรง มันเป็นเอกสาร 6 หน้าในมุมมองแนวตั้ง มันจะทำงานได้ถ้าคุณวางลงในการใช้งาน RootController ของแม่แบบ pageViewController

-(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];

    }

}

ฉันต้องการใช้สำหรับโหมดแนวนอนที่มีสองหน้า วิธีการใช้งานที่นั่น คุณช่วยแนะนำได้ไหม
iPhone โดยทางโปรแกรม

9

สวิฟท์ 4:

ฉันจำเป็นต้องไปที่ตัวควบคุมถัดไปเมื่อฉันแตะถัดไปบนตัวควบคุม pagecontroller และปรับปรุงดัชนี pageControl ดังนั้นนี่จึงเป็นทางออกที่ดีที่สุดและตรงไปตรงมาที่สุดสำหรับฉัน :

let pageController = self.parent as! PageViewController

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

pageController.pageControl.currentPage = 1

5

สิ่งที่เกี่ยวกับการใช้วิธีการจากแหล่งข้อมูล?

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

อะนาล็อกย้อนหลัง


3

ในสวิฟท์ :

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
คุณช่วยยกตัวอย่างที่สมบูรณ์ให้ฉันได้ไหม เพราะฉันกำลังทำบางสิ่งเช่นนี้ วิธีใช้ส่วนขยายนี้กับรหัสของฉัน หากคุณต้องการฉันสามารถส่งรหัสให้คุณ
Saty

2

อย่างไรก็ตามการใช้การเรียกเมธอด 'self.pageViewController setViewControllers' นี้ไม่ได้เรียกว่า 'viewDidDissapear' บน viewController สำหรับหน้าเว็บที่ถูกหันออกไปในขณะที่การเปลี่ยนหน้าด้วยตนเองจะเป็นการเรียก viewDidDissapear บนหน้าที่ถูกแยกออก ฉันเชื่อว่านี่เป็นสาเหตุของความผิดพลาดของฉัน

"จำนวนตัวควบคุมมุมมองที่มีให้ (0) ไม่ตรงกับจำนวนที่ต้องการ (1) สำหรับการเปลี่ยนภาพที่ร้องขอ"


ลองใช้: - pageViewController: DidFinishAnimating: previousViewControllers: transitionCompleted:
Graham

2

ฉันต้องการปุ่มเพื่อนำทางไปทางซ้ายบน PageViewController หนึ่งที่ควรทำสิ่งที่คุณคาดหวังจากการเคลื่อนไหวปัด

เนื่องจากฉันมีกฎบางอย่างอยู่ใน " pageViewController: viewControllerBeforeViewController " เพื่อจัดการกับการนำทางแบบปัดตามธรรมชาติฉันต้องการปุ่มเพื่อใช้รหัสนั้นซ้ำทั้งหมดและไม่สามารถใช้ดัชนีเฉพาะได้เพื่อเข้าถึงหน้าเว็บก่อนหน้าได้ คำตอบไม่ได้ ดังนั้นฉันต้องใช้ทางเลือกอื่น

โปรดทราบว่ารหัสต่อไปนี้สำหรับตัวควบคุมการดูหน้าเว็บซึ่งเป็นคุณสมบัติภายใน ViewController ที่กำหนดเองของฉันและมีการตั้งค่ากระดูกสันหลังเป็นกลาง

นี่คือรหัสที่ฉันเขียนสำหรับปุ่มการนำทางด้านซ้ายของฉัน:

- (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];
    }
}

คุณสามารถทำสิ่งที่คล้ายกันมากเพื่อสร้างปุ่มการนำทางที่ถูกต้องจากที่นี่


2

ในกรณีที่หน้าควบคุมเพื่อระบุหน้าปัจจุบันเป็น O && คุณต้องการให้หน้าเลื่อนผ่านทางเลื่อน & โดยการคลิกปุ่มที่กำหนดเองใน Page ViewController ด้านล่างอาจเป็นประโยชน์

//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];        
}

// ตัวแทนที่เรียกว่า viewControllerAfterViewController เมื่อผู้ใช้เลื่อนไปที่หน้าถัดไป

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

}

// ตรรกะของปุ่ม (ก่อนหน้า & ถัดไป)

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

คุณโพสต์คำตอบเดียวกันกับคำถามสี่ข้อเกือบทั้งหมดแล้ว หากคุณคิดว่าหนึ่งในนั้นซ้ำกันคุณควรทำเครื่องหมายเป็นเช่นนั้น (และไม่โพสต์คำตอบเดียวกันหลายครั้ง)
Jaap

ดังนั้นฉันสามารถโพสต์ลิงก์ของคำถามนี้ผ่านคำถามที่คล้ายกันอื่น ๆ
Yogesh Lolusare

1
ฉันไม่ได้ตั้งใจที่จะตัดสินหรืออะไร แต่การจัดรูปแบบรหัสของคุณดูไม่ค่อยน่าสนใจสำหรับฉัน
Lukas Petr

1
ใช่ @ Lukas ฉันจะจัดรูปแบบทันที ขอบคุณ
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];

}

// ตอนนี้เรียกวิธีนี้

[ตนเองย้ายไปที่หน้า];

ฉันหวังว่ามันจะทำงาน :)


1

สำหรับหน้าเดียวฉันเพิ่งแก้ไขคำตอบของ @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

@samwize ชี้ให้เห็นว่าวิธีการให้เลขหน้าโดยใช้

setViewControllers:array

นี่คือวิธีที่ฉันทำ: ฉันมีแหล่งข้อมูลและผู้รับมอบสิทธิ์แยกจากกัน คุณสามารถเรียกวิธีนี้และเปลี่ยนมุมมอง "ถัดไป" เท่านั้น ก่อนหน้านี้คุณต้องใช้กฎการเพจ นั่นคือคุณต้องตรวจสอบทิศทางและตัวควบคุมถัดไป ถ้าคุณใช้วิธีนั้นกับแหล่งข้อมูลที่กำหนดเองอาเรย์ของตัวควบคุมที่คุณแสดงจะไม่เปลี่ยนแปลง (เนื่องจากคุณจะใช้อาเรย์ที่กำหนดเองในคลาสย่อย NSObject)

การใช้แหล่งข้อมูลของคุณเองเพียงแค่ตั้งค่ามุมมองใหม่ (พร้อมทิศทางที่เฉพาะเจาะจง) เนื่องจากคุณจะยังคงควบคุมหน้าที่จะแสดงเมื่อกวาดตามปกติ


0

ฉันทำงานตั้งแต่เมื่อวานและในที่สุดก็ทำงานได้ ฉันไม่สามารถใช้เทมเพลตมาตรฐานทั้งหมดได้เพราะฉันมีมุมมองที่แตกต่างกันสามรายการเป็นผู้ดูย่อย:

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

ฉันต้องการปุ่มทริกเกอร์ใน VC แรกเท่านั้นดังนั้นฉันจึงเพิ่มคุณสมบัติหนึ่งรายการสำหรับ pageViewController และรุ่น:

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

@interface VC1 : UIViewController

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

@end

ฉันเขียนเมธอด init ของโมเดลอีกครั้งเพื่อส่งสตอรีบอร์ดและ pageViewController เป็นพารามิเตอร์ดังนั้นฉันสามารถตั้งค่าเหล่านั้นเป็น VC1 ของฉัน:

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

ในที่สุดฉันเพิ่ม IBAction ใน vc1 ของฉันเพื่อเรียกใช้วิธีการpageViewController setViewControllers: ทิศทาง: เคลื่อนไหว: เสร็จสมบูรณ์ ::

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

หมายเหตุฉันไม่จำเป็นต้องค้นหาดัชนี VCs ปุ่มของฉันจะนำฉันไปที่ VC ที่สองของฉัน แต่มันไม่ยากเลยที่จะรับดัชนีทั้งหมดและติดตามดูลูก ๆ ของคุณ:

- (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];
}

ฉันหวังว่ามันจะช่วยคุณ!


0

นี่เป็นวิธีการแก้ปัญหาโดยใช้วิธีการUIPageViewControllerDataSource :

รหัสติดตามของตัวควบคุมมุมมองปัจจุบันแสดงในUIPageViewController

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

การเริ่มต้นครั้งแรกcurrentViewControllerไปเริ่มต้นการตั้งมุมมองควบคุมสำหรับUIPageViewController

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

จากนั้นติดตามcurrentViewControllerในUIPageViewControllerDelegateวิธีการ: 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;
    }
}

สุดท้ายในวิธีการที่คุณเลือก (ในตัวอย่างด้านล่างของ- (IBAction) onNext: (ID) ส่ง ) คุณสามารถเขียนโปรแกรมสลับไปยังตัวควบคุมถัดไปหรือก่อนโดยใช้UIPageViewControllerDataSouceวิธีpageViewController: viewControllerBeforeViewController: , pageViewController: viewControllerAfterViewController:ที่จะได้รับ ตัวควบคุมมุมมองถัดไปหรือก่อนหน้าและนำทางไปยังมันโดยเรียก[self.pageViewController setViewControllers: @ [vc] ทิศทาง: UIPageViewControllerNavigationDirectionForward เคลื่อนไหว: เสร็จสมบูรณ์ใช่: ไม่มี];


- (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];
    }
}

คำอธิบายโดยละเอียดจะมีประโยชน์มาก
Taslim Oseni

@TaslimOseni ขอบคุณที่ชี้ให้เห็นว่าตัวอย่างไม่ชัดเจนเพียงพอ ฉันได้เพิ่มคำอธิบายวิธีการใช้งานโปรดแจ้งให้เราทราบหากต้องการคำอธิบายเพิ่มเติม
pconor

0

เนื่องจาก ViewControllers ฝังอยู่ใน PageViewController สิ่งที่คุณต้องทำคือ:

  • ดึงตัวควบคุมมุมมองผู้ปกครองและโยนเป็นคลาสที่เกี่ยวข้องของคุณ
  • ใช้คุณสมบัติแหล่งข้อมูลของผู้ปกครองเพื่อรับ ViewController ถัดไป
  • ใช้เมธอด SetParentViewControllers เพื่อตั้งค่าและเปลี่ยนเป็นหน้าถัดไป

ตัวอย่างใน Xamarin แต่ฟังก์ชั่นคล้ายกับ Swift และอื่น ๆ รหัสต่อไปนี้จะอยู่ในปุ่มคลิกผู้รับมอบสิทธิ์ในหนึ่งใน ViewControllers ที่แสดงเป็นหน้า:

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

parent.SetViewControllers(new UIViewController[] { next }, UIPageViewControllerNavigationDirection.Forward, true, null);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.