iOS - UIPageViewControllerDataSource方法调用两次

时间:2014-04-08 01:56:10

标签: ios objective-c uipageviewcontroller

我发现两个UIPageViewControllerDataSource方法存在一个奇怪的问题:我第一次进入页面视图控制器场景并拖动控制器的内容,无论拖动方向是什么,两个数据源方法被调用。我想当我在第一页并向右拖动时,这意味着在第一页之前没有更多的页面,这两种方法都不应该被调用。如果我向左拖动,只应调用after方法。

我跟着this post设置了视图控制器(除了我在故事板上没有单独的页面视图控制器。我使用传统的[UIPAgeViewController alloc] init]方法来实例化控制器)。以下是我的代码:

对于实际显示页面视图控制器内容的视图控制器(仅显示viewDidLoad的相关部分):

 - (void)viewDidLoad 
{
    // initialize page view controller
    _pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
    self.pageViewController.delegate = self;
    self.pageViewController.dataSource = self;

    // set up the initial scene of the page view controller
    UIViewController *viewController = [self viewControllerAtIndex:0];
    [self.pageViewController setViewControllers:@[viewController]
                                      direction:UIPageViewControllerNavigationDirectionForward
                                       animated:NO
                                     completion:nil];

    // adjust the size of the page view controller, -44 to show the buttons at the bottom
    self.pageViewController.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - 44);

    // display the content of the page view controller
    [self addChildViewController:self.pageViewController];
    [self.view addSubview:self.pageViewController.view];
    [self.pageViewController didMoveToParentViewController:self];
}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
      viewControllerBeforeViewController:(UIViewController *)viewController
{
    NSUInteger index = ((PWCPageContentViewController *)viewController).index;
    if (index == 0 || index == NSNotFound) {
        return nil;
    }
    --index;
    return [self viewControllerAtIndex:index];
}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
       viewControllerAfterViewController:(UIViewController *)viewController
{
    NSUInteger index = ((PWCPageContentViewController *)viewController).index;
    if (index == self.numberOfPages - 1 || index == NSNotFound) {
        return nil;
    }
    ++index;
    return [self viewControllerAtIndex:index];
}

- (PWCPageContentViewController *)viewControllerAtIndex:(NSUInteger)index
{
    PWCPageContentViewController *viewController =
    [self.storyboard instantiateViewControllerWithIdentifier:@"PageContentViewController"];
    viewController.index = index;
    NSString *text = [self.notes getNoteAtIndex:index];
    [viewController.textView setText:text];

    return viewController;
}

对于PWCPageContentViewController.h:

#import <UIKit/UIKit.h>

@class PWCNotes;

@interface PWCPageContentViewController : UIViewController <UITextViewDelegate>

@property NSUInteger index;
@property (weak, nonatomic) IBOutlet UITextView *textView;

- (void)dismissKeyboard;

@end

对于PWCPageContentViewController.m:

#import "PWCPageContentViewController.h"

@interface PWCPageContentViewController ()

@end

@implementation PWCPageContentViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.textView.delegate = self;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)dismissKeyboard
{
    if ([self.textView isFirstResponder]) {
        // dismiss the keyboard when hitting save
        [self.textView resignFirstResponder];
    }
}

@end

这是一个已知问题还是我错过了什么?

4 个答案:

答案 0 :(得分:5)

Swift

解决此问题

我在使用3 UIPageViewController以上时遇到了这个错误(例如,使用@ Rashad的代码段尝试4 UIPageViewController)。问题来自于缺少和未实现的可选UIPageViewControllerDelegate方法,这使得UIPageControl变得疯狂和不稳定。

请找到修复以下错误的特定方法:

/*
    Optional UIPageViewControllerDelegate method

    Sent when a gesture-initiated transition ends. The 'finished' parameter indicates whether
    the animation finished, while the 'completed' parameter indicates whether the transition completed or bailed out (if the user let go early).
*/
func pageViewController(pageViewController: UIPageViewController,
    didFinishAnimating finished: Bool,
    previousViewControllers: [AnyObject],
    transitionCompleted completed: Bool)
{
    // Turn is either finished or aborted
    if (completed && finished) {
        let currentDisplayedViewController = self.pageViewController!.viewControllers[0] as! ContentViewController
        self.pageControl.currentPage = currentDisplayedViewController.index
    }
}

如果您想获得完整的工作项目,请在下面找到Github链接:

Github link of the project

答案 1 :(得分:2)

UIPageViewController使用这些波纹管方法获取后面和前面的ViewController。

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController;
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController;

虽然它很奇怪但是它是一个已知的问题。每次调用Before和After方法获取VC。如果没有下一个VC,则返回nil,如果没有先前的VC,则datasourceDelegate返回nil,否则返回VC的索引。

UIPageViewControllerDelegate中,有一个名为:

的函数
 - (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers;

看看这可能有助于从pendingViewControllers数组中获取当前或下一个/上一个viewcontroller。

希望这会有所帮助.. :)

答案 2 :(得分:1)

正如@Rashad建议的那样,pageViewController:willTransitionToViewControllers:并没有搞砸。当您转换到上一个/下一个视图控制器时(前一个/下一个视图控制器不是nil),它只调用一次。这也适用于pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted:,在动画结束时只调用一次。

因此,如果您想要执行任何基于索引的事情,并且想要为即将到来的视图控制器获取正确的索引,或者您希望获得正确的视图控制器,请考虑使用这两种方法作为现在的解决方法。 / p>

答案 3 :(得分:1)

将过渡样式从滚动更改为pageCurl

pageViewController = UIPageViewController(transitionStyle:.pageCurl,navigationOrientation:.horizo​​ntal,options:nil)

它看起来更好,不会再调用两次