滑动最后一个视图控制器后,如何关闭/弹出 UIPageViewController?

Posted

技术标签:

【中文标题】滑动最后一个视图控制器后,如何关闭/弹出 UIPageViewController?【英文标题】:How can I dismiss/pop a UIPageViewController after the last view controller is swiped? 【发布时间】:2014-01-23 17:25:04 【问题描述】:

如何在最后一个视图控制器被滑动后关闭/弹出 UIPageViewController? 基本上想用图像制作一个教程风格的分页视图,并在用户从最后一个页面滑动到“下一个”页面后关闭。

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

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


    index++;

    if (index == 5) 
        [self.navigationController popViewControllerAnimated:YES]; // this doesn't do anything
        return nil;
    

    return [self viewControllerAtIndex:index];

【问题讨论】:

你可以在 *** 找到大量的解决方案。请不要超载太多。 我还没有找到任何东西,这就是我发布的原因。 [self dimissViewController] 或 [self.navigationcontroller popviewcontoller] 你会在哪里打这个电话? 我会让它变得更复杂,在你的索引上添加一个观察者并在值对应于最后一个时弹出:) 【参考方案1】:

这是我使用过的简单解决方案:

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

index == 5 返回空控制器并添加此UIPageViewControllerDelegate 方法:

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

    EmailTutorialViewController *viewController = 
                [pendingViewControllers objectAtIndex:0];
    if ([viewController index] == 5) 
    
        [self.navigationController popViewControllerAnimated:YES];
    

【讨论】:

不得不修改一大堆其他委托方法,但感谢初学者【参考方案2】:

在符合 UIPageViewControllerDelegate 协议的 UIPageViewController 或 viewController 中:

// UIPageViewController.h
@interface UIPageViewController

@property (nonatomic, assign) NSInteger pageIndex;

@end

// UIPageViewController.m
@implementation UIPageViewController

/* ... */

- (void)viewDidLoad

    [super viewDidLoad];

    // Start with animation from the presenting view/item.
    UIViewController *singlePageVC = [UIViewController viewControllerWithPageIndex:self.pageIndex];
    singlePageVC.view.alpha = 0.0f;
    if (singlePageVC != nil) 
        self.dataSource = self;
        self.delegate = self;

        // Add singlePageVC to the page view controller with the initial pageIndex.
        [self setViewControllers:@[ singlePageVC ]
                       direction:UIPageViewControllerNavigationDirectionForward
                        animated:NO
                      completion:nil];
    


#pragma mark - UIPageViewControllerDelegate

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

    NSInteger index = singlePageVC.pageIndex;
    // This will add a page before the current view controller.
    // Even if the index is 0, a new (dismissing) view controller will be added here.
    return [UIViewController viewControllerWithPageIndex:index - 1];


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

    NSInteger index = singlePageVC.pageIndex;
    // This will add a page after the current view controller.
    // Even if the index is at your array bounds (i.e., 5), a new (dismissing) view controller will be added here.
    return [UIViewController viewControllerWithPageIndex:index + 1];


/* ... */

@end

// UIViewController+PageIndex.h
extern NSString * const UIViewControllerShouldDismissFromPageViewControllerNotification;

@interface UIViewController (PageIndex)

@property (nonatomic, assign) NSInteger pageIndex;

- (instancetype)initWithPageIndex:(NSInteger)pageIndex;
+ (instancetype)viewControllerWithPageIndex:(NSInteger)pageIndex;

@end

// UIViewController+PageIndex.m
NSString * const UIViewControllerShouldDismissFromPageViewControllerNotification = @"UIViewControllerShouldDismissFromPageViewControllerNotification";

@implementation UIViewController (PageIndex)

// Initialize with the current item's index.
- (instancetype)initWithPageIndex:(NSInteger)pageIndex

    self = [super init];
    if (self) 
        _pageIndex = pageIndex;
    
    return self;


+ (instancetype)viewControllerWithPageIndex:(NSInteger)pageIndex

    return [[self alloc] initWithPageIndex:pageIndex];


- (void)viewWillAppear:(BOOL)animated

    [super viewWillAppear:animated];

    // Check for pageIndex out of bounds of your array.
    // This will be either less than 0 or greater or equal to your array count.
    if (self.pageIndex < 0 || self.pageIndex >= array.count)  // Replace with your global or passed array here.
        // Post dismiss notification here.
        [[NSNotificationCenter defaultCenter]
        postNotificationName:UIViewControllerShouldDismissFromPageViewControllerNotification
        object:nil];
        return;
    


@end

// View controller than manages your UIPageViewController.

@implementation YourViewController

/* ... */

- (void)viewDidLoad

    [[NSNotificationCenter defaultCenter]
    addObserver:self selector:@selector(dismissPageViewController:)
    name:UIViewControllerShouldDismissFromPageViewControllerNotification
    object:nil];


- (void)dismissPageViewController:(NSNotification *)notification

    // Dismiss your page view controllers here.
    [self.pageViewController dismissViewController];
    self.pageViewController = nil;

    // Or remove the page view controllers from its parent view controller,
    [self.pageViewController willMoveToParentViewController:nil];
    [self.pageViewController removeFromParentViewController];
    [self.pageViewController didMoveToParentViewController:nil];

    // Or its view from its super view.
    [self.pageViewController.view removeFromSuperview];
    self.pageViewController = nil;


/* ... */

@end

【讨论】:

以上是关于滑动最后一个视图控制器后,如何关闭/弹出 UIPageViewController?的主要内容,如果未能解决你的问题,请参考以下文章

如何从弹出视图中关闭第二个视图控制器

在表格视图中选择项目后无法关闭弹出框

Swift - 手动转换后关闭最后一个视图控制器

关闭后弹出视图控制器

向下滑动关闭垂直滚动视图

ios:如何关闭模态视图控制器,然后弹出推送的视图控制器