UIPageViewController: geçerli görünür görünümü döndür


89

Bir içinde görüntülenen geçerli sayfanın / görünümün ne olduğunu nasıl anlarsınız UIPageViewController?

viewDidAppearÇocuğumun görüşlerinin yöntemini geçersiz kıldım , böylece viewDidAppearyöntemlerinde üst görünüme bir kimlik gönderirler .

Ancak sorun şudur: Bu kimliği görüntülenen sayfa için kimlik olarak güvenilir bir şekilde kullanamıyorum. çünkü kullanıcı sayfayı çevirir ancak tam ortada çevirmeyi durdurup sayfayı geri koymaya karar verirse viewDidAppear, zaten çağrılmış olacaktır. (görünüm kıvrılmış sayfanın arkasından görülebilir).

Belki de sadece mevcut görünüm kaybolursa yeni bir kimliğe geçmeliyim. Ancak şu anda görünür durumda olan görünüme geri dönmenin daha basit bir yolu olup olmadığını merak ediyorum.


Onun viewDidAppear:animated:yerine kullanmayı denedin mi?
Till

O Evet. Bunu kullandım. Hatamı düzeltmek için soruyu düzenledim.
Ocak 2011

Soruyu düzenleme şeklin bana mantıklı gelmiyor. Bu kimliği ya viewWillAppear içinden ya da viewDidAppear'dan gönderirsiniz. Lütfen düzenlemenizi tekrar kontrol edin.
Till

Üzgünüm, soruyu düzenlemekle kötü bir iş yaptım. Başından beri viewDidAppear kullandım. Umarım son düzenlemem bunu netleştirir.
Ocak

Buraya bir göz atın çocuklar, bu benim için çalışıyor stackoverflow.com/a/36860663/4286947
theDC

Yanıtlar:


103

Mevcut sayfayı manuel olarak takip etmelisiniz. Temsilci yöntemi pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted:size bu değişkeni ne zaman güncelleyeceğinizi söyleyecektir. Yöntemin son argümanı, transitionCompleted:bir kullanıcının bir sayfa çevirme geçişini tamamlayıp tamamlamadığını size söyleyebilir.


1
Doğru cevap için +1 - Keşke UIPageViewController ile çalışma ve yalnızca iOS5'i destekleme şansım olsaydı.
Till

Teşekkürler, tam da aradığım temiz çözüm buydu. sayfalardaki delegelerden daha iyi.
Ocak 2011

3
Cihazı döndürdüğünüzde mevcut sayfayı nasıl takip ediyorsunuz?
Satyam

@ yapabilinceye kadar, projenizin minimum sürümünü ios5.0 olarak ayarlayın
mtmurdock

84
Mevcut sayfa numarasını artırıp azaltmayacağınızı nasıl anlarsınız?
şim

59

viewControllersİOS 6 itibariyle, UIPageViewController özelliğinin sürekli olarak güncellendiğini, böylece her zaman geçerli sayfayı temsil eden tek görünüm denetleyicisini tutacağını ve başka hiçbir şey olmadığını buldum . Böylece, viewControllers[0](Bir seferde yalnızca bir görünüm denetleyicisi gösterdiğinizi varsayarak) arayarak mevcut sayfaya erişebilirsiniz .

ViewController dizisi yalnızca sayfa yerine "kilitlendiğinde" güncellenir; bu nedenle, bir kullanıcı sonraki sayfayı kısmen göstermeye karar verirse, geçişi tamamlamadıkça "geçerli" sayfa olmaz.

"Sayfa numaralarını" takip etmek istiyorsanız, görünüm denetleyicilerinize UIPageViewController veri kaynağı yöntemleriyle onları oluştururken bir dizin değeri atayın.


Yani mesela:

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

Fakat bunun güvenilmez olduğu yorumlarına dikkat edin .


2
Güvenilmez buldum. Sorunun kaynağını bulamadım. Animasyon bittiğinde, viewControllersözelliğe erişiyorum ve doğru görünüm kontrolörlerini alıyorum ancak döndürdüğümde, yöntemde spineLocationForInterfaceOrientationartık doğru görünüm kontrolörlerini alamıyorum. Bu yüzden, her zaman .tml dosyasına güvenmek yerine kendi currentPage özelliğimi korumaya devam ettim viewControllers.
Fábio Oliveira

İlginç, bu özel durumlarda nasıl davrandığını görmek için biraz oynayacağım
Eddy Borja

2
Ben de güvenilmez buldum. Görünüşe göre Apple, her sayfa dönüşü için viewControllerBeforeViewController veya viewControllerAfterViewController'ı çağırıyor, ancak UIPageViewController.viewControllers'ı güncellemiyor. Bu tür şeyleri nasıl yanlış anlıyorlar bilmiyorum ama yapıyorlar. İş yükümü gerçekten artırıyor ve kodumun netliğini bozuyor (genellikle DRY ve diğer ilkeleri ihlal ediyor).
Zack Morris

3
@ZackMorris. Kesinlikle inanılmaz, çok haklısın. Bu bir "Apple korku anı". Neden, neden birini sağa taşıma, şu anda hangi sayfadayım, vb. Gibi bariz işlevleri içermiyorlar? "Bulunduğunuz sayfayı alamamanız inanılmaz !!!"
Şişko

1
self.viewControllers [0] benim için iyi çalışıyor gibi görünüyor. Ancak başlatma sırasında setViewControllers'ı bir kez çağırıp gerisini otomasyona bıraktım. (iOS 8.4'te test edildi)
Bob

45

Ne yazık ki, yukarıdaki tüm yöntemler bana yardımcı olmadı. Yine de çözümü etiketleri kullanarak buldum. En iyisi olmayabilir, ancak işe yarıyor ve birine yardımcı olmasını umuyoruz:

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

Swift'de : ( @Jessy sayesinde )

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

Örnek: ana fikir


3
Bu en basit gibi görünüyor ve benim için iyi sonuç verdi. Görünüm denetleyicileri eklerken etiketleri ayarlıyorum (örneğin, HelpPage1ViewController * page1 = [self.storyboard instantiateViewControllerWithIdentifier: @ "page1"]; page1.view.tag = 0;). Ardından, nerede olduğunuzu takip etmek için ana görünüm denetleyicisi için bir currentPage özelliği ayarlayabilirsiniz. Yalnızca veri kaynağını değil, her iki protokolü ("<UIPageViewControllerDataSource, UIPageViewControllerDelegate>") eklediğinizden ve temsilciyi self ("self.pageViewController.delegate = self;") olarak ayarladığınızdan emin olun, aksi takdirde yöntem çağrılmaz. Bu beni biraz şaşırttı.
James Toomey

1
@VictorM bu çözüm benim için çalışmıyor. Farklı görüntülere sahip bir pageViewController'ım var. Her kaydırmada 0 etiketi döndürmeye devam ediyor, bunun neden olduğu hakkında bir fikriniz var mı? Şimdiden teşekkürler
theDC

1
@VictorM Birkaç gün harcadım, dizini kaydetmeye çalıştım, ancak yanlışlıkla bu cevabı buldum, keşke 1000 kez oy verebilseydim, teşekkür ederim!
Evgeniy Kleban

1
Harika çözüm Teşekkürler, bunun üstesinden gelmek için saatler harcadı
Vision Mkhabela

Yalnızca 0 değerini döndürür. Yanlış bir şey mi yapıyorum
N. Der

35

Ole'nin Cevabına Dayalıyor…

Geçerli sayfayı izlemek ve sayfa göstergesini doğru dizine güncellemek için 4 yöntemi bu şekilde uyguladım:

- (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
Bence, bir geçiş tamamlanmadığında dizini düzgün şekilde geri yüklemek self.nextIndex = self.currentIndexyerine son satırın olması gerektiğini düşünüyorum self.nextIndex = 0. Aksi takdirde currentIndex, sayfalarınızın ortasında bir yerde hızlı bir şekilde ileri geri sayfalandırırken 0 değeri ile sonuçlanma riskiniz vardır .
hverlind

1
Bu benim için tam olarak çalışmıyor. Bazen pageViewController: willTransitionToViewControllers çağrılmaz ve bu nedenle nextIndex değiştirilmez ve bu durumda geçerli dizin yanlış olur.
Hayden Holligan

31

Aşağıdaki çözüm benim için çalıştı.

Apple, yerel UIPageViewController kaydırma görünümü sayfalandırmasını daha yapılandırılabilir hale getirerek pek çok güçlüğü önleyebilir. Yerel UIPageViewController sayfalandırması, görünüm çerçevesi içinde şeffaf bir arka planı veya yeniden konumlandırmayı desteklemediği için yeni bir UIView ve UIPageControl'ü üst üste bindirmek zorunda kaldım.

- (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
bunda indeksle ne demek istiyorsun
Yohan

İndeksi alıyorum (yani, self.pageViewController.viewControllers dizisindeki mevcut görünüm denetleyicisinin konumunu temsil eden tamsayı) ve ardından self.pageControl öğesinin currentPage özniteliğini ayarlamak için kullanıyorum (bir tamsayı değeri bekleniyor) . Mantıklı olmak?
sirvine

6
endeks burada özel bir özellik olduğuna inanıyorum
Adam Johns

bununla ilgili sorun, animasyon yöntemi olmadan sayfayı değiştirmek isterseniz çağrılmayacağıdır
Silviu St

19

Swift 4

Gereksiz kod yok. Bunu yapmanın 3 yolu. UIPageViewControllerDelegate yöntemini kullanma .

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

Tanrıya şükür! Bilmiyordum pageViewController.viewControllers. ViewControllers'ı nereden tanıyorsunuz? .Birincisi söz konusu olan?
Senaryo Kitty

Aslında oldukça basit, viewControllers dizisi yalnızca şu anda sunulan görünüm denetleyicisini içerir.
Nikola Milicevic

2
bu fonksiyondan indeks değişkenine nasıl erişebilirim?
N. Der

11

Küçük bir işlev kullanarak ve pageIndex'i statik NSInteger olarak belirterek sayfa dizinini izliyorum.

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

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

ve [self setPageIndex];Ole tarafından belirtilen işlevin içinde ve ayrıca yönelimdeki değişikliği algıladıktan sonra.


5

İlk olarak Corey'in çözümünü kullandım, ancak iOS5 üzerinde çalışmıyordu ve sonra

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

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

Farklı sayfalar arasında geçiş yapmayı denedi ve şimdilik iyi çalışıyor.


3

Ne yazık ki yukarıdaki hiçbir şey benim için çalışmıyor.

İki görünüm denetleyicim var ve son görünümü geriye doğru biraz (yaklaşık 20 piksel) kaydırdığımda, temsilciyi tetikliyor:

pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted:

ve geçerli sayfanın (dizin) 0hangisinin yanlış olduğunu söylemek.

Child viewController içinde temsilci kullanma şunun gibi bir şey:

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

// and a property

@property (nonatomic) NSInteger index;

şu şekilde tetiklenir viewDidAppear:

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

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

Benim için çalıştı.


3

Bu benim için güvenilir bir şekilde çalışıyor

Özel bir UIPageController'ım var. Bu pageController.currentPage, görünümde görüntülenen UIViewController'dan güncellenirWillAppear

   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

Bir süredir kullanıyorum view.tag, mevcut sayfayı takip etmeye çalışmak çok karmaşıktı.

Bu kodda, indeks tagher birinin özelliği içinde saklanır viewve sonraki veya önceki VC'yi getirmek için kullanılır. Bu yöntemi kullanarak sonsuz bir kaydırma oluşturmak da mümkündür. Bu çözümü de görüntülemek için yorum koduna bakın:

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

Cevabınız için teşekkürler arkadaşlar, benzer bir sorunla karşılaştım, indeksi saklamak zorunda kaldım. Kodumu biraz değiştiriyorum, aşağıya yapıştırıyorum:

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

Basit bir görüntü kaydırıcı öğreticisi uygulayarak bunun nasıl yapıldığını gösteren demo kodunun altında (Swift 2'de). Kodun kendisindeki yorumlar:

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

UIPageViewController'da görüntülediğim bir viewControllers dizim var .

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

Burada dikkat edilmesi gereken önemli nokta, UIPageViewController'ın setViewControllers yönteminin herhangi bir temsilci geri araması vermemesidir . Temsilci geri aramaları yalnızca UIPageViewController'daki kullanıcı dokunma eylemlerini temsil eder .


0

Bulduğum çözüm bu:

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

Kullanım:

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

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

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

İlk başlığı ayarladığınızdan emin olun


0

Bu IMHO'ya yaklaşmanın en basit yolu, geçişin olası sonucunu saklamak için PageControl'ü kullanmak ve ardından geçiş iptal edildiyse geri dönmektir. Bu, kullanıcı kaydırmaya başlar başlamaz sayfa kontrolünün değiştiği anlamına gelir, ki bu benim için sorun değil. Bu, kendi UIViewControllers dizinize sahip olmanızı gerektirir (bu örnekte adı verilir 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

viewControllerDoğrudan UIPageViewController(Swift 4 sürümünden) istemeye ne dersiniz :

fileprivate weak var currentlyPresentedVC: UIViewController?

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

Veya, bir noktada yalnızca şu anda sunulan görünüm denetleyicisine ihtiyacınız varsa pageViewController.viewControllers?.first, o anda kullanın .


0

Hızlı 5'de ve sıralı yanıtın ardından

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
        }

    }

} 

Bu durumda hangi UIViewController sınıfının gömülü olduğu umrumda değil


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

Mevcut sayfa dizinini döndürecektir. ve bu kodu UIPageViewController'ın (didFinishAnimating) temsilci işlevi altında kullanması gerekir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.