Tell When a UIPageViewController is Scrolling (for Parallax Scrolling of an Image)

后端 未结 8 1917
灰色年华
灰色年华 2020-12-13 04:43

I am trying to make an effect similar to that found in the new Yahoo weather app. Basically, each page in the UIPageViewController has a background image, and w

相关标签:
8条回答
  • 2020-12-13 04:47
    extension UIPageViewController {
    
        var scrollView: UIScrollView? {
    
            return view.subviews.filter { $0 is UIScrollView }.first as? UIScrollView
        }
    }
    

    Using:

    pageController.scrollView?.delegate = self
    
    0 讨论(0)
  • 2020-12-13 04:50

    Use @Paul's snippet -

    for (UIView *v in self.pageViewController.view.subviews) {
    if ([v isKindOfClass:[UIScrollView class]]) {
        ((UIScrollView *)v).delegate = self;
    }
    }
    

    to implement this protocol : -(void)scrollViewDidScroll:(UIScrollView *)scrollView

    -(void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
    CGPoint point = scrollView.contentOffset;
    
    float percentComplete;
    percentComplete = fabs(point.x - self.view.frame.size.width)/self.view.frame.size.width;
    NSLog(@"percentComplete: %f", percentComplete);
    }
    

    This gives you the percentage completion of the scroll. Happy coding!

    0 讨论(0)
  • 2020-12-13 04:57

    My guess is that it is not a UIPageViewController, but rather a paged UIScrollView. The UIScrollView does give you a constantly repeated delegate method that tracks what is happening as the scrolling takes place.

    Alternatively, you might be able to access the paged UIScrollView that the UIPageViewController is secretly using, but you might break something, and I'm not sure how Apple would feel about it.

    0 讨论(0)
  • 2020-12-13 04:58

    In Swift 3 you could write it even shorter:

    if let scrollView = self.pageViewController.view.subviews.first(where: { $0 is UIScrollView }) as? UIScrollView {
        scrollView.delegate = self
    }
    
    0 讨论(0)
  • 2020-12-13 05:00

    You are not supposed to change the delegate of the page view controller's scroll view: it can break its normal behaviour and/or not be supported later on.

    Instead, you can:

    1. Add a pan gesture to the page view controller's view:

      let panGesture = UIPanGestureRecognizer(target: self, action: #selector(panRecognized(gesture:)))
      view.addGestureRecognizer(panGesture)
      panGesture.delegate = self
      
    2. Add the new function in order to know how the view is being scrolled.

      @objc func panRecognized(gesture: UIPanGestureRecognizer) {
          // Do whatever you need with the gesture.translation(in: view)
      }
      
    3. Declare your ViewController as UIGestureRecognizerDelegate.

    4. Implement this function:

      func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
          return true
      }
      
    0 讨论(0)
  • 2020-12-13 05:03

    What you are looking for is called parallax scrolling, you can find several libraries that can help you with that.

    Edit: Matt is right this is not an answer, only a hint. Anyway let's complete it:

    For animating a background image that lay behind your UIPageViewController you should use the delegate methods that it offer:

    -[id<UIPageViewControllerDelegate> pageViewController:willTransitionToViewControllers:]
    -[id<UIPageViewControllerDelegate> pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted:]
    

    With these two methods you can calculate the percentage of the scrolling (you should store your controllers in your array to know at which controller you scrolled to and get the percentage)

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