Apakah mungkin untuk Mengubah halaman secara terprogram dalam UIPageViewController?

161

Apakah mungkin untuk mengaktifkan halaman secara program UIPageViewController?

RAGOpoR
sumber
1
dapatkah Anda memposting kode contoh untuk itu? Terima kasih untukmu
iPhone Secara pemrograman

Jawaban:

235

Ya itu mungkin dengan metode:

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

Itu adalah metode yang sama yang digunakan untuk mengatur pengontrol tampilan pertama pada halaman. Serupa, Anda dapat menggunakannya untuk pergi ke halaman lain.

Bertanya-tanya mengapa viewControllersarray, dan bukan pengontrol tampilan tunggal?

Itu karena pengontrol tampilan halaman dapat memiliki "tulang belakang" (seperti di iBooks), menampilkan 2 halaman konten sekaligus. Jika Anda menampilkan 1 halaman konten pada suatu waktu, maka kirimkan saja 1 elemen array.

Contoh dalam Swift:

pageContainer.setViewControllers([displayThisViewController], direction: .Forward, animated: true, completion: nil)
samwize
sumber
2
Sekarang NDA sudah habis, bisakah ini diperluas sedikit lagi? Mungkin contoh kode.
SpaceTrucker
11
Saya pikir saya akhirnya mengerti ini: UIPageViewController tidak terlalu peduli tentang halaman apa yang sedang aktif. Ketika Anda memanggil setViewControllers, itu dapat membuatnya tampak bahwa Anda menavigasi animasi jauh dari pengontrol tampilan saat ini, tetapi itu tidak benar-benar mencari ke halaman.
Amy
3
contoh: [self setViewControllers: @ [vcToMoveTo] arah: UIPageViewControllerNavigationDirectionForward animated: YES completion: nil]; // di mana vcToMoveTo adalah UIViewController
finneycanhelp
1
Jika Anda ingin terus menggunakan UIPageControl, maka Anda mungkin ingin: self.currentIndex = indeks viewControllerToMoveTo kemudian untuk presentasiIndexForPageViewController kembali self.currentIndex
brendan
3
Periksa stackoverflow.com/questions/22554877/... jika Anda juga perlu memperbarui tampilan indikator halaman
Protongun
37

Karena saya membutuhkan ini juga, saya akan membahas lebih detail tentang bagaimana melakukan ini.

Catatan: Saya berasumsi Anda menggunakan formulir templat standar untuk membuat UIPageViewControllerstruktur Anda - yang memiliki modelViewControllerdan dataViewControllerdibuat saat Anda memintanya. Jika Anda tidak mengerti apa yang saya tulis - kembalilah dan buat proyek baru yang menggunakan UIPageViewControllerdasar apa adanya. Anda akan mengerti itu.

Jadi, perlu membalik ke halaman tertentu melibatkan pengaturan berbagai potongan metode yang tercantum di atas. Untuk latihan ini, saya berasumsi bahwa ini adalah tampilan lanskap dengan dua tampilan ditampilkan. Juga, saya menerapkan ini sebagai IBAction sehingga bisa dilakukan dari tekan tombol atau yang tidak - itu hanya mudah untuk membuatnya panggilan pemilih dan mengirimkan item yang dibutuhkan.

Jadi, untuk contoh ini Anda memerlukan dua pengontrol tampilan yang akan ditampilkan - dan opsional, apakah Anda akan maju dalam buku atau mundur.

Perhatikan bahwa saya hanya memiliki hard-coded ke mana harus pergi ke halaman 4 & 5 dan menggunakan slip ke depan. Dari sini Anda dapat melihat bahwa yang perlu Anda lakukan hanyalah memasukkan variabel yang akan membantu Anda mendapatkan item-item ini ...

-(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!  

}
Joe
sumber
2
Saya memiliki persyaratan yang sama untuk pindah ke halaman tertentu. Tetapi kode di atas sepertinya tidak bekerja untuk saya. Apa yang saya lakukan salah? Saya memiliki 19 halaman.
GaneshT
Bisakah kita menggunakan potongan kode ini juga ketika memberikan pengontrol tampilan melalui objek sumber data?
Jens Kohl
20
Kelas yang aneh sekali diimplementasikan dengan buruk, Apple.
devios1
29

Berikut contoh kode lain untuk tampilan satu halaman. Implementasi untuk viewControllerAtIndex dihilangkan di sini, itu harus mengembalikan controller tampilan yang benar untuk indeks yang diberikan.

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

Halaman dapat diubah dengan menelepon

[self changePage:UIPageViewControllerNavigationDirectionReverse];
[self changePage:UIPageViewControllerNavigationDirectionForward];
lekksi
sumber
Tetapi kontrol indeks halaman tidak diperbarui. Bagaimana aku melakukan itu?
thatzprem
1
Jawaban ini berfungsi baik untuk saya - perhatikan bahwa jika Anda mengandalkan metode delegasi "didFinishAnimating" dari UIPageViewController, mereka tidak akan dipecat. Alih-alih, pindahkan kode Anda dari didFinishAnimating ke metode terpisah dan panggil metode itu dari blok penyelesaian pada metode setViewControllers.
DiscDev
1
@thatzprem Jika Anda ingin terus menggunakan UIPageControl, maka Anda mungkin ingin: self.currentIndex = indeks viewControllerToMoveTo kemudian untuk presentasiIndexForPageViewController kembali self.currentIndex
brendan
@ thatzprem benar. Setiap kali akan ke halaman yang sama. Misalnya jika kita memiliki 3 halaman, maka setiap kali akan ke halaman ke-2 saja.
Tushar Lathiya
18

Saya benar-benar bisa melewatkan sesuatu di sini, tetapi solusi ini tampaknya jauh lebih sederhana daripada yang banyak diusulkan.

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)
            }
        }
    }
}
wfbarksdale
sumber
1
Bagus sekali! Hanya perlu juga mengubah indikator halaman entah bagaimana.
TruMan1
Sangat membantu! Tolong beri kami fungsi untuk goToFirstPage juga.
Mamta
Setiap kali akan ke halaman yang sama. Misalnya jika kita memiliki 3 halaman, maka setiap kali akan ke halaman ke-2 saja.
Tushar Lathiya
15

Kode ini bekerja dengan baik untuk saya, terima kasih.

Inilah yang saya lakukan dengan itu. Beberapa metode untuk melangkah maju atau mundur dan satu metode untuk langsung ke halaman tertentu. Untuk dokumen 6 halaman dalam tampilan potret. Ini akan berfungsi baik jika Anda menempelkannya ke dalam implementasi RootController dari template 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];

    }

}
Graham
sumber
saya ingin menggunakannya untuk mode lansekap di mana ada dua halaman. cara menggunakannya di sana. bisakah kamu membimbing.
iPhone Secara pemrograman
9

Swift 4:

Saya harus pergi ke pengontrol berikutnya ketika saya mengetuk berikutnya pada pengontrol tampilan pagecontroller dan juga memperbarui indeks pageControl, jadi ini adalah solusi terbaik dan paling mudah bagi saya :

let pageController = self.parent as! PageViewController

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

pageController.pageControl.currentPage = 1
Sam Bing
sumber
5

Bagaimana dengan menggunakan metode dari dataSource?

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

Secara analog untuk mundur.

JakubKnejzlik
sumber
3

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

}
Raja-Penyihir
sumber
1
Bisakah Anda memberi saya contoh lengkap untuk ini? Karena aku melakukan hal seperti ini. Cara menggunakan ekstensi ini dengan kode saya. Jika Anda mau, saya bisa mengirimkan kode.
Saty
2

Namun menggunakan panggilan metode 'self.pageViewController setViewControllers' ini tidak memanggil 'viewDidDissapear' pada viewController untuk halaman yang telah ditolak, sedangkan membalikkan halaman secara manual akan memanggil viewDidDissapear pada halaman yang ditolak. Saya percaya ini adalah penyebab kecelakaan saya

"Jumlah pengontrol tampilan yang disediakan (0) tidak cocok dengan jumlah yang diperlukan (1) untuk transisi yang diminta"

noRema
sumber
coba gunakan: - pageViewController: didFinishAnimating: priorViewControllers: transitionCompleted:
Graham
2

Saya juga membutuhkan tombol untuk bernavigasi ke kiri pada PageViewController, yang harus melakukan apa yang Anda harapkan dari gerakan geser.

Karena saya sudah memiliki beberapa aturan di dalam " pageViewController: viewControllerBeforeViewController " untuk berurusan dengan navigasi swipe natural, saya ingin tombol untuk menggunakan kembali semua kode itu, dan tidak bisa menggunakan indeks spesifik untuk menjangkau halaman seperti sebelumnya jawaban itu. Jadi, saya harus mengambil solusi alternatif.

Harap perhatikan bahwa kode berikut ini untuk Pengontrol Tampilan Halaman yang merupakan properti di dalam ViewController kustom saya, dan tulang punggungnya telah disetel ke pertengahan.

Berikut adalah kode yang saya tulis untuk tombol Navigasi Kiri saya:

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

Anda dapat melakukan sesuatu yang sangat mirip untuk membuat tombol navigasi kanan dari sini.

tuliomir
sumber
2

Dalam hal jika KONTROL HALAMAN untuk menunjukkan halaman saat ini adalah O&& Anda ingin halaman bernavigasi melalui gulir & juga dengan mengklik tombol kustom di Page ViewController, di bawah ini mungkin bermanfaat.

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

// Delegasikan disebut viewControllerAfterViewController ketika Pengguna Gulir ke halaman berikutnya

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

}

// Logika tombol Khusus (Sebelumnya & berikutnya)

-(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;}
Yogesh Lolusare
sumber
Anda telah memposting jawaban yang hampir sama persis untuk empat pertanyaan. Jika Anda berpikir salah satu dari mereka adalah duplikat dari yang lain, Anda harus menandai mereka seperti itu (dan tidak memposting jawaban yang sama beberapa kali).
Jaap
Jadi saya dapat memposting tautan pertanyaan ini ke pertanyaan serupa lainnya tetapi solusinya sama.
Yogesh Lolusare
1
Saya tidak bermaksud menghakimi atau apa pun, tetapi pemformatan kode Anda terlihat sangat mengecewakan bagi saya.
Lukas Petr
1
@Lukas, saya akan memformatnya sekarang. Terima kasih
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];

}

// sekarang panggil metode ini

[self moveToPage];

Semoga berhasil :)

D. Garcia
sumber
1

Untuk satu halaman, saya baru saja mengedit jawaban @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];
}
Smit Shah
sumber
0

Seperti @samwize tunjukkan, cara membuat halaman dengan menggunakan

setViewControllers:array

Inilah cara saya melakukannya: Saya memiliki sumber data dan delegasi saya terpisah. Anda dapat memanggil metode ini dan hanya mengubah tampilan "berikutnya". Sebelumnya Anda harus menerapkan aturan paging. Artinya, Anda harus memeriksa arah dan pengontrol berikutnya. Jika Anda menggunakan metode itu dengan sumber data khusus Anda, array pengontrol yang Anda tampilkan tidak akan berubah (karena Anda akan menggunakan array khusus pada subkelas NSObject).

Menggunakan sumber data Anda sendiri, metode ini hanya menetapkan tampilan baru (dengan arah tertentu). Karena Anda masih akan mengontrol halaman yang akan ditampilkan ketika biasanya digesek.

serigala
sumber
0

Saya mengerjakannya sejak kemarin dan akhirnya saya berhasil. Saya tidak bisa menggunakan template standar sama sekali, karena saya memiliki tiga viewControllers berbeda sebagai tampilan anak:

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

Saya membutuhkan tombol pemicu hanya di VC yang pertama, jadi saya menambahkan satu properti untuk pageViewController dan model:

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

@interface VC1 : UIViewController

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

@end

Saya menulis ulang metode init model untuk meneruskan storyboard dan pageViewController sebagai parameter, jadi saya bisa mengaturnya ke VC1 saya:

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

Akhirnya, saya menambahkan IBAction di vc1 saya untuk memicu metode setViewControllers pageViewController: arah: animasi: selesai ::

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

Catatan Saya tidak perlu menemukan indeks VC, tombol saya akan membawa saya ke VC kedua, tetapi ini tidak sulit untuk mendapatkan semua indeks, dan melacak jejak anak Anda:

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

Saya harap ini membantu Anda!

Thomás Calmon
sumber
0

Berikut ini solusi menggunakan metode UIPageViewControllerDataSource :

Kode melacak pengontrol tampilan yang ditampilkan saat ini di UIPageViewController .

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

Pertama-tama inisialisasi currentViewController ke set pengontrol tampilan awal untuk UIPageViewController .

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

Kemudian melacak currentViewController di UIPageViewControllerDelegate metode: pageViewController: willTransitionToViewControllers: dan 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;
    }
}

Akhirnya, dalam metode pilihan Anda (dalam contoh di bawah itu - (IBAction) onNext: (id) sender ), Anda dapat pemrograman beralih ke controller berikutnya atau sebelumnya menggunakan UIPageViewControllerDataSouce metode pageViewController: viewControllerBeforeViewController: , pageViewController: viewControllerAfterViewController: untuk mendapatkan pengontrol tampilan berikutnya atau sebelumnya dan navigasikan ke sana dengan memanggil [self.pageViewController setViewControllers: @ [vc] arah: UIPageViewControllerNavigationDirectionAktif animasi ke depan: YA selesai: 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];
    }
}
pconor
sumber
Penjelasan terperinci akan sangat berguna.
Taslim Oseni
@TaslimOseni terima kasih telah menunjukkan bahwa contohnya tidak cukup jelas. Saya menambahkan deskripsi cara kerjanya, beri tahu saya jika perlu penjelasan lebih lanjut.
pconor
0

Karena ViewControllers tertanam dalam PageViewController, yang harus Anda lakukan adalah:

  • Ambil pengontrol tampilan induk dan buat sebagai kelas Anda yang relevan.
  • Gunakan properti sumber data orang tua itu untuk mendapatkan ViewController berikutnya.
  • Gunakan metode SetParentViewControllers untuk mengatur dan beralih ke halaman berikutnya.

Contoh di Xamarin, tetapi secara fungsional mirip dengan Swift dll. Kode berikut akan berada di delegasi Klik Tombol di salah satu ViewControllers yang ditampilkan sebagai halaman:

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

parent.SetViewControllers(new UIViewController[] { next }, UIPageViewControllerNavigationDirection.Forward, true, null);
Hibah K
sumber