UIPageViewController: повернення поточного видимого подання


89

Звідки ви знаєте, яка поточна сторінка / подання відображається всередині UIPageViewController?

Я перевизначив viewDidAppearметод своїх дочірніх поглядів, так що вони надсилають ідентифікатор батьківському поданню у своєму viewDidAppearметоді.

Однак проблема полягає в наступному: я не можу надійно використовувати цей ідентифікатор як ідентифікатор для відображеної сторінки. тому що якщо користувач перегортає сторінку, але на півдорозі вирішує зупинити перегортання і повернути сторінку назад, viewDidAppearце вже буде викликано. (вид видно за згорнутою сторінкою).

Можливо, мені слід перейти на новий ідентифікатор, лише якщо поточний вигляд зникне. Але цікаво, чи немає більш простого способу повернути вид, який наразі видно?


Ви пробували використовувати viewDidAppear:animated:замість цього?
До

О, так. Я справді цим користувався. Я відредагував запитання, щоб виправити свою помилку.
січня

Те, як ви редагували запитання, для мене немає сенсу. Або ви надсилаєте цей ідентифікатор із viewWillAppear або з viewDidAppear. Будь ласка, перевірте редагування.
До

На жаль, я погано попрацював над редагуванням запитання. Я весь час використовував viewDidAppear. Сподіваюся, моя остання редакція це пояснює.
січня

Погляньте сюди , хлопці, це працює для мене stackoverflow.com/a/36860663/4286947
TheDC

Відповіді:


103

Слід відстежувати поточну сторінку вручну. Метод делегування pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted:повідомляє вам, коли слід оновити цю змінну. Останній аргумент методу transitionCompleted:може сказати вам, завершив користувач перехід на перегортання сторінки чи ні.


1
+1 за правильну відповідь - хотілося б, щоб у мене була можливість працювати з UIPageViewController і підтримувати лише iOS5.
До

Дякую, це саме те чисте рішення, яке я шукав. краще, ніж делегати на сторінках.
січня

3
Як обертати пристрій, як ви відстежуєте поточну сторінку?
Сатьям

@ до тих пір, поки не зможеш, просто встанови мінімальну версію свого проекту на ios5.0
mtmurdock

83
Як ви можете визначити, збільшувати чи зменшувати номер поточної сторінки?
шим

59

Станом на iOS 6 я виявив, що viewControllersвластивість UIPageViewController постійно оновлюється, так що в ньому завжди буде один контролер подання, що представляє поточну сторінку, і нічого іншого. Таким чином, ви можете отримати доступ до поточної сторінки, зателефонувавшиviewControllers[0] (припускаючи, що ви показуєте лише один контролер перегляду одночасно).

Масив viewController оновлюється лише після того, як сторінка "зафіксується" на своєму місці, тому, якщо користувач вирішить частково відкрити наступну сторінку, він не стане "поточною" сторінкою, якщо вони не завершать перехід.

Якщо ви хочете відстежувати "номери сторінок", призначте контролерам подання значення індексу під час їх створення за допомогою методів джерела даних UIPageViewController.


Так наприклад:

-(void)autoAdvance
    {
    UIViewController *currentVC = self.viewControllers[0];
    NSUInteger currentIndex = [myViewControllers indexOfObject:currentVC];

    if ( currentIndex >= (myViewControllers.count-1) ) return;

    [self setViewControllers:@[myViewControllers[ currentIndex+1 ]]
        direction:UIPageViewControllerNavigationDirectionForward
        animated:YES
        completion:nil];
    }
-(NSInteger)presentationIndexForPageViewController:
                         (UIPageViewController *)pageViewController
    {
    // return 0;
    UIViewController *currentVC = self.viewControllers[0];
    NSUInteger currentIndex = [myViewControllers indexOfObject:currentVC];
    return currentIndex;
    }

Але зверніть увагу на коментарі, що це ненадійно.


2
Я виявив, що це ненадійно. Не вдалося знайти джерело проблеми. Коли анімація закінчується, я отримую доступ до viewControllersвластивості, і я отримую правильні контролери перегляду, але коли я обертаю метод spineLocationForInterfaceOrientation, я більше не отримую правильних контролерів перегляду. Тому я дотримувався збереження власного властивості currentPage, замість того, щоб завжди покладатися на viewControllers.
Фабіо Олівейра,

Цікаво, я трохи пограю з цим, щоб побачити, як він поводиться в цих особливих випадках
Едді Борха

2
Я також виявив, що це ненадійно. Здається, Apple просто викликає viewControllerBeforeViewController або viewControllerAfterViewController для кожного перегортання сторінки, але не оновлює UIPageViewController.viewControllers. Я не знаю, як їм вдається неправильно сприймати подібні речі, але вони це роблять. Це дійсно підвищує моє робоче навантаження та порушує ясність мого коду (часто порушуючи DRY та інші принципи).
Zack Morris

3
@ZackMorris. Це абсолютно неймовірно, ти цілком маєш рацію. Це «момент жаху Apple». Чому б їм не включити такі очевидні функції, як переміщення однієї вправо, на якій сторінці я зараз і т. Д. Цілком неймовірно, що ви не можете "отримати сторінку, на якій перебуваєте !!!"
Fattie

1
self.viewControllers [0], здається, добре працює для мене. Але я просто один раз викликаю setViewControllers під час ініціації, а решту залишаю автоматизації. (протестовано в iOS 8.4)
Боб,

45

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

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed 
{
    if (completed) {
        int currentIndex = ((UIViewController *)self.pageViewController.viewControllers.firstObject).view.tag;
        self.pageControl.currentPage = currentIndex;
    }
}

In Swift: (завдяки @Jessy )

func pageViewController(pageViewController: UIPageViewController,
    didFinishAnimating finished: Bool,
    previousViewControllers: [UIViewController],
    transitionCompleted completed: Bool)
{
    guard completed else { return }
    self.pageControl.currentPage = pageViewController.viewControllers!.first!.view.tag
}

Приклад: суть


3
Це здається найбільш прямим і добре працювало для мене. Я встановив теги для додавання контролерів подання (наприклад, HelpPage1ViewController * page1 = [self.storyboard instantiateViewControllerWithIdentifier: @ "page1"]; page1.view.tag = 0;). Потім ви можете встановити властивість currentPage для головного контролера перегляду, щоб відстежувати, де ви знаходитесь. Обов’язково додайте обидва протоколи ("<UIPageViewControllerDataSource, UIPageViewControllerDelegate>"), а не тільки джерело даних, і встановіть делегата на self ("self.pageViewController.delegate = self;"), інакше метод не буде викликаний. Це мене трохи збило з пантелику.
James Toomey

1
@VictorM це рішення для мене не працює. У мене є pageViewController з різними зображеннями. Він продовжує повертати тег 0 при кожному проведенні, будь-яка ідея, чому це відбувається? Заздалегідь
дякую

1
@VictorM я витратив кілька днів, намагаючись зберегти індекс, але випадково знайшов цю відповідь, хотів би, щоб міг проголосувати 1000 разів, дякую!
Євген Клебан

1
Чудове рішення Спасибі витратив години, намагаючись обійти це
Vision Mkhabela

Повертає лише значення 0. Я щось роблю не так
Н. Дер

35

Спираючись на відповідь Оле…

Ось як я застосував 4 методи для відстеження поточної сторінки та оновлення показника сторінки до правильного індексу:

- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController{

    return (NSInteger)[self.model count];

}

- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController{

    return (NSInteger)self.currentIndex;
}

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

    SJJeanViewController* controller = [pendingViewControllers firstObject];
    self.nextIndex = [self indexOfViewController:controller];

}

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed{

    if(completed){

        self.currentIndex = self.nextIndex;

    }

    self.nextIndex = 0;

}

2
Я думаю, що останній рядок повинен бути self.nextIndex = self.currentIndexзамість self.nextIndex = 0того, щоб правильно відновити індекс, коли перехід не завершено. В іншому випадку ви ризикуєте отримати currentIndexзначення 0, коли швидко переглядаєте сторінки вперед-назад десь посередині ваших сторінок.
hverlind

1
Це не повністю працює для мене. Іноді pageViewController: willTransitionToViewControllers не викликається, а отже nextIndex не змінюється, а поточний індекс тоді помилковий.
Хайден Холліган,

31

Рішення нижче працювало для мене.

Apple могла уникнути багатьох клопотів, зробивши рідну пагінацію подання прокрутки UIPageViewController більш конфігуруваною. Мені довелося вдатися до накладання нових UIView та UIPageControl лише тому, що рідна пагінація UIPageViewController не підтримує прозорий фон або перестановку в рамці подання.

- (void)pageViewController:(UIPageViewController *)pvc didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
  if (!completed)
  {
    return;
  }
  NSUInteger currentIndex = [[self.pageViewController.viewControllers lastObject] index];
  self.pageControl.currentPage = currentIndex;
}

1
в цьому, що ви маєте на увазі під індексом?
Йохан

Я отримую індекс (тобто ціле число, яке представляє позицію поточного контролера подання в масиві self.pageViewController.viewControllers), а потім використовую це для встановлення атрибута currentPage self.pageControl (який очікує цілочисельного значення) . Мати сенс?
sirvine

6
index - це властивість, що я вважаю, тут
Адам Джонс,

проблема з цим полягає в тому, що якщо ви хочете змінити сторінку без анімації, метод виклику не буде викликаний
Сільвіу Сент

19

Стрімкий 4

Немає зайвого коду. 3 способи зробити це. Використання методу UIPageViewControllerDelegate .

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    guard completed else { return }

    // using content viewcontroller's index
    guard let index = (pageViewController.viewControllers?.first as? ContentViewController)?.index else { return }

    // using viewcontroller's view tag
    guard let index = pageViewController.viewControllers?.first?.view.tag else { return }

    // switch on viewcontroller
    guard let vc = pageViewController.viewControllers?.first else { return }
    let index: Int
    switch vc {
    case is FirstViewController:
        index = 0
    case is SecondViewController:
        index = 1
    default:
        index = 2
    }
}

Дякую, Боже! Я не знав про pageViewController.viewControllers. Звідки ви знаєте viewControllers?. Перший - це той, про який йде мова?
Сценарій Кітті

Насправді дуже просто, масив viewControllers містить лише представлений на даний момент контролер подання.
Нікола Мілічевич

2
як отримати доступ до змінної індексу поза цією функцією?
N. Der

11

Я відстежую індекс сторінки, використовуючи невелику функцію та вказуючи pageIndex як статичний NSInteger.

-(void) setPageIndex
{
    DataViewController *theCurrentViewController = [self.pageViewController.viewControllers objectAtIndex:0];

    pageIndex = [self.modelController indexOfViewController:theCurrentViewController];
}

і виклик [self setPageIndex];усередині функції, визначеної Оле, а також після виявлення зміни орієнтації.


5

Спочатку я використовував рішення Кори, але воно не працювало на iOS5, а потім закінчилося використанням,

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed{

    if(completed) {
        _currentViewController = [pageViewController.viewControllers lastObject];
    }
}

Він спробував переключитись між різними сторінками, і поки це працює добре.


3

На жаль, нічого вище для мене не працює.

У мене є два контролери перегляду, і коли я трохи (близько 20 пікселів) прокручую останній вигляд назад, це запускає делегата:

pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted:

і сказати, що поточна сторінка (індекс) є 0 є неправильною.

Використання делегата всередині дочірнього видуController приблизно так:

- (void)ViewController:(id)VC didShowWithIndex:(long)page;

// and a property

@property (nonatomic) NSInteger index;

що запускається всередині, viewDidAppearяк:

- (void)viewDidAppear:(BOOL)animated
{
    ...

    [self.delegate ViewController:self didShowWithIndex:self.index];
}

Працював у мене.


3

Це працює мені надійно

У мене є власний UIPageController. Ця сторінкаController.currentPage оновлюється з відображеного UIViewController у поданніWillAppear

   var delegate: PageViewControllerUpdateCurrentPageNumberDelegate?

      init(delegate: PageViewControllerUpdateCurrentPageNumberDelegate ){
        self.delegate = delegate
        super.init(nibName: nil, bundle: nil)
      }

      required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
      }

    override func viewWillAppear(animated: Bool) {

        if delegate != nil {
          self.delegate!.upateCurrentPageNumber(0) //(0) is the pageNumber corresponding to the displayed controller
        }
      } 

    //In the pageViewController 

    protocol PageViewControllerUpdateCurrentPageNumberDelegate {

      func upateCurrentPageNumber(currentPageIndex: Int)
    }

     create the view display controllers initializing with the delegate

    orderedViewControllers = {
              return [
                IntroductionFirstPageViewController(delegate: self),
                IntroductionSecondPageViewController(delegate: self),
                IntroductionThirdPageViewController(delegate: self)
              ]

            }()

    the function implementing the protocol

    func upateCurrentPageNumber(currentPageIndex: Int){
        pageControl.currentPage = currentPageIndex
      }

1

Я використовував view.tag вже деякий час, намагаючись відстежувати поточну сторінку було занадто складно.

У цьому коді індекс зберігається у tagвластивості кожного viewі використовується для отримання наступного або попереднього ВК. За допомогою цього методу також можна створити нескінченний сувій. Перегляньте коментар у коді, щоб також переглянути це рішення:

extension MyPageViewController: UIPageViewControllerDataSource {

  func viewControllerWithIndex(var index: Int) -> UIViewController! {
    let myViewController = storyboard?.instantiateViewControllerWithIdentifier("MyViewController") as MyViewController

    if let endIndex = records?.endIndex {
      if index < 0 || index >= endIndex { return nil }
      // Instead, We can normalize the index to be cyclical to create infinite scrolling
      // if index < 0 { index += endIndex }
      // index %= endIndex
    }

    myViewController.view.tag = index
    myViewController.record = records?[index]

    return myViewController
  }

  func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
    let index = viewController.view?.tag ?? 0
    return viewControllerWithIndex(index + 1)
  }

  func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
    let index = viewController.view?.tag ?? 0
    return viewControllerWithIndex(index - 1)
  }

  func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
    return records?.count ?? 0
  }

  func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
    return (pageViewController.viewControllers.first as? UIViewController)?.view.tag ?? 0
  }
}

1

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

- (MenuListViewController *)viewControllerAtIndex:(NSInteger)index {

    if (_menues.count < 1)
        return nil;

    //    MenuListViewController *childViewController = [MenuListViewController initWithSecondSetFakeItems];
    MenuListViewController *childViewController = self.menues[index];
    childViewController.index = index;

    return childViewController;
}

#pragma mark - Page View Controller Data Source

- (void)pageViewController:(UIPageViewController *)pageViewController
        didFinishAnimating:(BOOL)finished
   previousViewControllers:(NSArray<UIViewController *> *)previousViewControllers
       transitionCompleted:(BOOL)completed{

    if (completed) {

        NSUInteger currentIndex = ((MenuListViewController *)self.pageController.viewControllers.firstObject).index;
        NSLog(@"index %lu", (unsigned long)currentIndex);
    }
}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
    NSUInteger index = [(MenuListViewController *)viewController index];

    if (index == 0)
        return nil;

    index --;

    return [self viewControllerAtIndex:index];
}


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

    NSUInteger index = [(MenuListViewController *)viewController index];

    index ++;

    if (index == _menues.count)
        return nil;

    return [self viewControllerAtIndex:index];
}

0
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed {

    NSLog(@"Current Page = %@", pageViewController.viewControllers);

    UIViewController *currentView = [pageViewController.viewControllers objectAtIndex:0];

    if ([currentView isKindOfClass:[FirstPageViewController class]]) {
             NSLog(@"First View");
        }
        else if([currentView isKindOfClass:[SecondPageViewController class]]) {
             NSLog(@"Second View");
        }
        else if([currentView isKindOfClass:[ThirdViewController class]]) {
              NSLog(@"Third View");
        }
}

//pageViewController.viewControllers always return current visible View ViewController

0

Нижче демонстраційний код (у Swift 2), який демонструє, як це робиться шляхом реалізації простого навчального посібника із swiper. Коментарі до самого коду:

import UIKit

/*
VCTutorialImagePage represents one page show inside the UIPageViewController.
You should create this page in your interfacebuilder file:
- create a new view controller
- set its class to VCTutorialImagePage
- sets its storyboard identifier to "VCTutorialImagePage" (needed for the loadView function)
- put an imageView on it and set the contraints (I guess to top/bottom/left/right all to zero from the superview)
- connect it to the "imageView" outlet
*/

class VCTutorialImagePage : UIViewController {
    //image to display, configure this in interface builder
    @IBOutlet weak var imageView: UIImageView!
    //index of this page
    var pageIndex : Int = 0

    //loads a new view via the storyboard identifier
    static func loadView(pageIndex : Int, image : UIImage) -> VCTutorialImagePage {
        let storyboard = UIStoryboard(name: storyBoardHome, bundle: nil)
        let vc = storyboard.instantiateViewControllerWithIdentifier("VCTutorialImagePage") as! VCTutorialImagePage
        vc.imageView.image      = image
        vc.pageIndex            = pageIndex
        return vc
    }
}


/*
VCTutorialImageSwiper takes an array of images (= its model) and displays a UIPageViewController 
where each page is a VCTutorialImagePage that displays an image. It lets you swipe throught the 
images and will do a round-robbin : when you swipe past the last image it will jump back to the 
first one (and the other way arround).

In this process, it keeps track of the current displayed page index
*/

class VCTutorialImageSwiper: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {

    //our model = images we are showing
    let tutorialImages : [UIImage] = [UIImage(named: "image1")!, UIImage(named: "image2")!,UIImage(named: "image3")!,UIImage(named: "image4")!]
    //page currently being viewed
    private var currentPageIndex : Int = 0 {
        didSet {
            currentPageIndex=cap(currentPageIndex)
        }
    }
    //next page index, temp var for keeping track of the current page
    private var nextPageIndex : Int = 0


    //Mark: - life cylce


    override func viewDidLoad() {
        super.viewDidLoad()
        //setup page vc
        dataSource=self
        delegate=self
        setViewControllers([pageForindex(0)!], direction: .Forward, animated: false, completion: nil)
    }


    //Mark: - helper functions

    func cap(pageIndex : Int) -> Int{
        if pageIndex > (tutorialImages.count - 1) {
            return 0
        }
        if pageIndex < 0 {
            return (tutorialImages.count - 1)
        }
        return pageIndex
    }

    func carrouselJump() {
        currentPageIndex++
        setViewControllers([self.pageForindex(currentPageIndex)!], direction: .Forward, animated: true, completion: nil)
    }

    func pageForindex(pageIndex : Int) -> UIViewController? {
        guard (pageIndex < tutorialImages.count) && (pageIndex>=0) else { return nil }
        return VCTutorialImagePage.loadView(pageIndex, image: tutorialImages[pageIndex])
    }

    func indexForPage(vc : UIViewController) -> Int {
        guard let vc = vc as? VCTutorialImagePage else {
            preconditionFailure("VCPagImageSlidesTutorial page is not a VCTutorialImagePage")
        }
        return vc.pageIndex
    }


    //Mark: - UIPageView delegate/datasource


    func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
        return pageForindex(cap(indexForPage(viewController)+1))
    }

    func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
        return pageForindex(cap(indexForPage(viewController)-1))
    }

    func pageViewController(pageViewController: UIPageViewController, willTransitionToViewControllers pendingViewControllers: [UIViewController]) {
        nextPageIndex = indexForPage(pendingViewControllers.first!)
    }

    func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
        if !finished { return }
        currentPageIndex = nextPageIndex
    }

    func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
        return tutorialImages.count
    }

    func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
        return currentPageIndex
    }

}

0

У мене є масив viewControllers, який я відображаю в UIPageViewController .

extension MyViewController: UIPageViewControllerDataSource {

func presentationCount(for pageViewController: UIPageViewController) -> Int {
    return self.viewControllers.count
}

func presentationIndex(for pageViewController: UIPageViewController) -> Int {
    return self.currentPageIndex
}
}




extension MyViewController: UIPageViewControllerDelegate {

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {

    if !completed { return }

    guard let viewController = previousViewControllers.last, let index = indexOf(viewController: viewController) else {
        return
    }

    self.currentPageIndex = index

}

fileprivate func indexOf(viewController: UIViewController) -> Int? {
    let index = self.viewControllers.index(of: viewController)
    return index
}
}

Важливо відзначити, що метод setViewControllers методу UIPageViewController не дає жодного зворотного виклику. Делегатні зворотні виклики представляють лише дії дотику користувача в UIPageViewController .


0

Це рішення, яке я придумав:

class DefaultUIPageViewControllerDelegate: NSObject, UIPageViewControllerDelegate {

    // MARK: Public values
    var didTransitionToViewControllerCallback: ((UIViewController) -> Void)?

    // MARK: Private values
    private var viewControllerToTransitionTo: UIViewController!

    // MARK: Methods
    func pageViewController(
        _ pageViewController: UIPageViewController,
        willTransitionTo pendingViewControllers: [UIViewController]
    ) {
        viewControllerToTransitionTo = pendingViewControllers.last!
    }

    func pageViewController(
        _ pageViewController: UIPageViewController,
        didFinishAnimating finished: Bool,
        previousViewControllers: [UIViewController],
        transitionCompleted completed: Bool
    ) {
        didTransitionToViewControllerCallback?(viewControllerToTransitionTo)
    }
}

Використання:

 let pageViewController = UIPageViewController()
 let delegate = DefaultUIPageViewControllerDelegate()

 delegate.didTransitionToViewControllerCallback = {
    pageViewController.title = $0.title
 }

 pageViewController.title = viewControllers.first?.title
 pageViewController.delegate = delegate

Обов’язково встановіть початковий заголовок


0

Найпростіший спосіб наблизитися до цього IMHO - використовувати PageControl для зберігання потенційних результатів переходу, а потім повернути назад, якщо перехід було скасовано. Це означає, що елемент керування сторінками змінюється, як тільки користувач починає проводити пальцем, і це нормально для мене. Для цього потрібно мати власний масив UIViewControllers (у цьому прикладі називається allViewControllers)

func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
    if let index = self.allViewControllers.index(of: pendingViewControllers[0]) {
        self.pageControl.currentPage = index
    }
}

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    if !completed, let previousIndex = self.allViewControllers.index(of: previousViewControllers[0]) {
        self.pageControl.currentPage = previousIndex
    }
}

0

Як щодо того, щоб запитати viewControllerбезпосередньо у UIPageViewController(версія Swift 4):

fileprivate weak var currentlyPresentedVC: UIViewController?

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    currentlyPresentedVC = pageViewController.viewControllers?.first
}

Або, якщо вам просто потрібен представлений в даний момент контролер перегляду в якийсь момент часу, просто скористайтеся pageViewController.viewControllers?.firstцим часом.


0

Швидко 5 та наступна відповідь sirvine

extension InnerDetailViewController: UIPageViewControllerDelegate {

    func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {

        if completed {
            guard let newIndex = embeddedViewControllers.firstIndex(where: { $0 == pageViewController.viewControllers?.last }) else { return }
            print(newIndex)
            currentEmbeddedViewControllerIndex = newIndex
        }

    }

} 

У цьому випадку мені байдуже, який клас UIViewController вбудований


-1
UIViewController *viewController = [pageViewController.viewControllers objectAtIndex:0];
NSUInteger currentIndex = [(ViewController*) viewController indexNumber];

Він поверне поточний індекс сторінки. і повинен використовувати цей код під функцією делегування UIPageViewController (didFinishAnimating).

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