2016-04-26 62 views
2

我在尋找可靠的方式來跟蹤UIPageViewController當前索引。獲取UIPageViewController當前索引的可靠方法

這個問題是衆所周知的;雖然viewControllers正在正確呈現,但很難跟蹤當前的索引。

我認爲這將是很好的跨SO社區刷新這個話題,因爲它並沒有解決由於某種原因

我已經經歷了許多線程瀏覽這裏,但大多數的答案都是過時或標記爲不可靠的(結果取決於如果用戶做了一個完整的刷卡或只是一半滑動等)

我已經訪問this線程,但它沒有提供任何明確正確的答案。

我已經試過:

1)保持的viewController的視圖標籤的軌跡 - link - 總是返回0

2)在這兩個UIPageViewController方法在指數變化來看,viewControllerBeforeViewControllerviewControllerAfterViewControlle

其結果是不可預知的,有時它跳過一個索引等。

有沒有人想出一個好方法,可靠的方法跟蹤UIPageCiewController索引以使用它(例如打印當前索引)?

我很感激obj-c和swift的實現,但swift是我正在尋找的。

+0

我在那個鏈接的答案,但遺憾的是我的回答沒有任何upvotes,但使用委託是唯一的方法(至少對我來說),以正確地跟蹤指數。請讓我知道,如果你想看看我的執行(ObjC)... – 0yeoj

+0

我認爲@ 0yeoj解決方案是你在找什麼:http://stackoverflow.com/a/33818615/2301271 – Joshua

+0

@ 0yeoj隨意在這裏發佈你的實現,最好是快速的 – DCDC

回答

2

這是ObjC

ParentViewController

#import "PagesViewController.h" 

// Delegate: PageViewDelegate 
// Declared inside `PagesViewController` 
// 
@interface ParentViewController() <UIPageViewControllerDataSource, UIPageViewControllerDelegate, PageViewDelegate> 

@property (nonatomic) UIPageViewController *pageViewController; 

@end 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil]; 
    self.pageViewController.dataSource = self; 
    self.pageViewController.view.frame = self.view.frame; 

    // im setting page 3 as the default page 
    // 
    [self.pageViewController setViewControllers:[NSArray arrayWithObject:[self viewControllerAtIndex:3]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil]; 
    [self addChildViewController:self.pageViewController]; 
    [self.view addSubview:self.pageViewController.view]; 
} 

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

    if (index == 0) { 
     return nil; 
    } 

    index--; 

    return [self viewControllerAtIndex:index]; 
} 

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

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

    index++; 

    if (index == 5) { 
     return nil; 
    } 

    return [self viewControllerAtIndex:index]; 
} 

- (PagesViewController *)viewControllerAtIndex:(NSInteger)index 
{ 
    PagesViewController *vc = [[PagesViewController alloc] init]; 

    // set delegate here.. 
    // 
    vc.delegate = self; 

    // other data 
    // 
    vc.index = index; 
    vc.titleLabel = [NSString stringWithFormat:@"Screen :%ld", (long)index]; 

    return vc; 
} 

- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController 
{ // The number of items reflected in the page indicator. return x; } 

- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController 
{ // The selected item reflected in the page indicator. return x; } 

// This is what you need 
// 
- (void)viewController:(id)VC didShowWithIndex:(long)index 
{ 
    NSLog(@"didShowWithIndex: %ld", index); 
} 

PagesViewController.h

@protocol PageViewDelegate <NSObject> 

- (void)viewController:(id)VC didShowWithIndex:(long)index; 

@end 


@interface PagesViewController : UIViewController 

@property (weak) id <PageViewDelegate> delegate; 

@property (nonatomic) NSInteger index; 

@property (nonatomic) NSString *titleLabel; 

@end 

PagesViewController。米

@implementation PagesViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    self.view.backgroundColor = [UIColor blackColor]; 

    UILabel *titleLabel = [[UILabel alloc] initWithFrame:self.view.frame]; 
    titleLabel.textAlignment = NSTextAlignmentCenter; 
    titleLabel.textColor = [UIColor whiteColor]; 
    titleLabel.text = self.titleLabel; 
    [self.view addSubview:titleLabel]; 
} 

// Trigger delegate here 
// 
- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 

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

@end 
2

像@ 0yeoj建議的那樣,委託設計模式就是這裏的解決方案。它需要一些思考。

讓我們添加協議IndexDelegate和修改了一下PageContentViewController

protocol IndexDelegate { 
func showIndex(index:Int) 
} 

import UIKit 

class PageContentViewController: UIViewController { 

@IBOutlet weak var imageView: UIImageView! 
var delegate:IndexDelegate? 
var pageIndex:Int = 0 
var imageFile:String! 
override func viewDidLoad() { 
    super.viewDidLoad() 
    self.imageView.image = UIImage(named: self.imageFile) 
    } 
override func viewDidAppear(animated: Bool) { 
    self.delegate!.showIndex(self.pageIndex) 
    } 

現在在我們的父視圖控制器,我們遵守協議

func showIndex(index: Int) { 
    print(index) 
    } 

不要忘記設置yourPageContentViewControllerInstance.delegate = self 和繼承協議YourParentViewController:UIViewController, UIPageViewControllerDataSourceDelegate, IndexDelegate {}

就是這樣!完美可靠的工作,並沒有落後!

+0

你好DCDC,你在哪裏放置「yourPageContentViewControllerInstance.delegate = self」。你是否遍歷所有VControllers並分配委託=父級? – drdrdrdr

相關問題