Removing a view controller from UIPageViewController

前端 未结 12 2456
梦谈多话
梦谈多话 2020-11-28 19:22

It\'s odd that there\'s no straightforward way to do this. Consider the following scenario:

  1. You have a page view controller with 1 page.
  2. Add another p
相关标签:
12条回答
  • 2020-11-28 19:33

    Actually I think I solved the issue. This is what was happening in my app:

    1. UIViewController subclass instance was removed from UIPageViewController by removing it from model and setting viewControllers property of UIPageViewController to different ViewController. This is enough to do the job. No need to do any controller containment code on that controller
    2. The ViewController was gone, but I could still scroll to it by swiping right in my case.
    3. My issue was this. I was adding a custom gesture recognizer to ViewController displayed by UIPageViewController. This recognizer was hold as a strong property on the controller that also owned UIPageViewController.
    4. FIX: before loosing access to the ViewController being dismissed I made sure I properly cleaned all the memory it uses(dealloc) and removed the gesture recognizer
    5. Your mileage may vary, but I see no point for this solution to be wrong, when something's not working I first suspect my code :)
    0 讨论(0)
  • 2020-11-28 19:36

    I am just learning this myself, so take with a grain of salt, but from what I understand, you need to change the datasource of the pageviewcontroller, not remove the viewcontroller. How many pages are shown in a pageviewcontroller is determined by its datasource, not the viewcontrollers.

    0 讨论(0)
  • 2020-11-28 19:36

    This problem exists when you are trying to change viewControllers during swipe gesture animation between viewControllers. To solve this problem, i made a simple flag to discover when page view controller is during transition.

    - (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers {
        self.pageViewControllerTransitionInProgress = YES;
    }
    
    - (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed {
            self.pageViewControllerTransitionInProgress = NO;
    }
    

    And when i am trying to chenge view controller i am checking if there is transition in progress.

    - (void)setCurrentPage:(NSString *)newCurrentPageId animated:(BOOL)animated {
    
        if (self.pageViewControllerTransitionInProgress) {
            return;
        }
    
        [self.pageContentViewController setViewControllers:@[pageDetails] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:^(BOOL finished) {
        }
    
    }
    
    0 讨论(0)
  • 2020-11-28 19:39

    maq is right. If you are using the scrolling transition, removing a child view controller from the UIPageViewController does not prevent the deleted "page" from returning on-screen if the user navigates to it. If you're interested, here's how I removed the child view controller from the UIPageViewController.

    // deleteVC is a child view controller of the UIPageViewController
    [deleteVC willMoveToParentViewController:nil];
    [deleteVC.view removeFromSuperview];
    [deleteVC removeFromParentViewController]; 
    

    View controller deleteVC is removed from the childViewControllers property of the UIPageViewController, but still appears on-screen if the user navigates to it.

    Until someone smarter than me finds an elegant solution, here's a work around (it's a hack--so you have to ask yourself if you really need to remove pages from a UIPageViewController).

    These instructions assume that only one page is displayed at a time.

    After the user taps a button indicating that she would like to delete the page, navigate to the next or previous page using the setViewControllers:direction:animated:completion: method. Of course, you then need to delete the page's content from your data model.

    Next (and here's the hack), create and configure a brand new UIPageViewController and load it in the foreground (i.e., in front of the other UIPageViewController). Make sure that the new UIPageViewController starts off displaying the exact same page that was previously displayed. Your new UIPageViewController will fetch fresh view controllers from the data source.

    Finally, unload and destroy the UIPageViewController that's in the background.

    Anyway, maq asked a really good question. Unfortunately, I don't have enough reputation points to up vote the question. Ah, dare to dream... someday I will have 15 reputation points.

    0 讨论(0)
  • 2020-11-28 19:41

    Concluding Matt Mc's great answer, the following method could be added to a subclass of UIPageViewController, that way allowing the usage of setViewControllers:direction:animated:completion: as it was intended to be used if the bug would not be present.

    - (void) setViewControllers:(NSArray*)viewControllers direction:(UIPageViewControllerNavigationDirection)direction animated:(BOOL)animated completion:(void (^)(BOOL))completion {
    
        if (!animated) {
            [super setViewControllers:viewControllers direction:direction animated:NO completion:completion];
            return;
        }
    
        [super setViewControllers:viewControllers direction:direction animated:YES completion:^(BOOL finished){
    
            if (finished) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [super setViewControllers:viewControllers direction:direction animated:NO completion:completion];
                });
            } else {
                if (completion != NULL) {
                    completion(finished);
                }
            }
        }];
    }
    

    Now, simply call setViewControllers:direction:animated:completion: on the class/subclasses implementing this method, and it should work as expected.

    0 讨论(0)
  • 2020-11-28 19:41

    we are getting crash on tab change .So one solution i got is didChangeSelect of tabs disable the userintraction.

    0 讨论(0)
提交回复
热议问题