Чи можливо програмно перегортати сторінку в UIPageViewController?


Відповіді:


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
приклад: [self setViewControllers: @ [vcToMoveTo] напрям: UIPageViewControllerNavigationDirectionНаперед анімований: YES завершення: нуль]; // де vcToMoveTo - це UIViewController
finneycanhelp

1
Якщо ви хочете продовжувати користуватися UIPageControl, то, можливо, вам захочеться: self.currentIndex = viewControllerToMoveTo індекс, а потім для presentiIndexForPageViewController повернути 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 сторінок.
ГанешТ

Чи можемо ми використовувати цей фрагмент коду також при наданні контролерів перегляду через об’єкт джерела даних?
Єнс Кол

20
Який дивно погано реалізований клас, Apple.
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 повернути self.currentIndex
берндан

@thatzprem має рацію. Кожен раз, коли вона переходить на одну і ту ж сторінку. Наприклад, якщо у нас є 3 сторінки, то кожного разу вона буде переходити лише на другу сторінку.
Тушар Латхія

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.
Мамта

Кожен раз, коли вона переходить на одну і ту ж сторінку. Наприклад, якщо у нас є 3 сторінки, то кожного разу вона буде переходити лише на другу сторінку.
Тушар Латхія

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:

Мені потрібно було перейти до наступного контролера, коли я натискаю наступний на контролері перегляду сторінок, а також оновлюю індекс pageControl, тому це було найкращим і найпростішим рішенням для мене :

let pageController = self.parent as! PageViewController

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

pageController.pageControl.currentPage = 1

5

А як щодо використання методів данихSource?

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
Скажіть, будь ласка, повний приклад для цього. Тому що я роблю щось подібне. Як використовувати це розширення зі своїм кодом. Якщо ви хочете, я можу надіслати вам код.
Сб

2

Однак, використовуючи цей метод "self.pageViewController setViewControllers", виклик не викликає "viewDidDissapear" на viewController для сторінки, яка була відвернута, тоді як перевернення сторінки вручну робить виклик viewDidDissapear на відхиленій сторінці. Я вважаю, що це причина моєї краху

"Кількість наданих контролерів перегляду (0) не відповідає необхідній кількості (1) для запитуваного переходу"


спробуйте використовувати: - pageViewController: didFinishAnimating: попереднійViewControllers: переходЗавершено:
Грем

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

У випадку, якщо PAGE CONTROL для вказівки поточної сторінки є 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

Тож я можу розмістити посилання цього питання на інше подібне питання, але рішення те саме.
Йогеш Лолусар

1
Я не маю на увазі судити чи нічого, але форматування вашого коду для мене виглядає дуже неприємно.
Лукас Петро

1
Право @Lukas, я зараз його відформатую. Спасибі
Йогеш Лолусаре

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

}

// тепер виклик цього методу

[self moveToPage];

Я сподіваюся, що це працює :)


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

Я працюю над ним з вчорашнього дня, і я нарешті зробив це. Я не міг використати стандартний шаблон повністю, тому що у мене є три різні елементи viewControllers як перегляди дітей:

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

Мені потрібна була тригерна кнопка лише в першому ВК, тому я додав одну властивість для 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, щоб запустити сторінкуViewController метод setViewControllers: напрям: анімований: завершення ::

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

Зауважте, що мені не потрібно знаходити індекси ДК, моя кнопка переводить мене до другого ВК, але не важко отримати всі індекси та відслідковувати ваші дитячі уявлення:

- (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] напрямок: UIPageViewControllerNavigationDirectionНаперед анімований: YES завершення: 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];
    }
}

Детальне пояснення було б дуже корисним.
Таслім Осені

@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);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.