Tell When a UIPageViewController is Scrolling (for

2020-02-07 17:38发布

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 when scrolling through the page view, the Image's location only scrolls about half the speed. How would I do that? I thought I could use some sort of Delegate Method in the UIPageViewController to get the current offset and then update the images like that. The only problem is that I cannot find anyway to tell if the UIPageViewController is being scrolled! Is there a method for that? Thanks!

7条回答
爷、活的狠高调
2楼-- · 2020-02-07 18:01
extension UIPageViewController {

    var scrollView: UIScrollView? {

        return view.subviews.filter { $0 is UIScrollView }.first as? UIScrollView
    }
}

Using:

pageController.scrollView?.delegate = self
查看更多
爱情/是我丢掉的垃圾
3楼-- · 2020-02-07 18:04

I would do this:

Objective-C

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

and implement this protocol

- (void)scrollViewDidScroll:(UIScrollView *)scrollView

Swift

for view in self.pageViewController.view.subviews {
  if let scrollView = view as? UIScrollView {
    scrollView.delegate = self
  }
}

and implement this protocol

func scrollViewDidScroll(scrollView: UIScrollView)
查看更多
乱世女痞
4楼-- · 2020-02-07 18:09

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
}
查看更多
神经病院院长
5楼-- · 2020-02-07 18:11

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!

查看更多
【Aperson】
6楼-- · 2020-02-07 18:16

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)

查看更多
做个烂人
7楼-- · 2020-02-07 18:21
for (UIView *view in self.pageViewController.view.subviews) {
    if ([view isKindOfClass:[UIScrollView class]]) {
         [(UIScrollView *)view setDelegate:self];
    }
} 

this gives you access to all standard scroll view API methods. And this is not using private Apple API's.

I added traversing through subviews, to 100% find the UIPageViewController's inner scroll view WARNING: Be careful with scrollview.contentOffset. It resets as the controller scrolls to new pages

If you need persision scrollview offset tracking and stuff like that, it would be better to use a UICollectionViewController with cells sized as the collection view itself and paging enabled.

查看更多
登录 后发表回答