我想在页面滚动过程中从uipageviewcontroller接收更新。我想知道%的transitionProgress。 (当用户移动手指以进入另一页时,此值应更新)。我对从一个页面到另一个页面的动画进度感兴趣,而不是通过总页数进展。
到目前为止我发现了什么:
有一个名为UICollectionViewTransitionLayout的类具有与我要查找的属性相对应的属性“transitionProgress”。可能uipageviewcontroller会以某种方式实现这个方法吗?
我可以在uipagecontroller上调用以下方法,但结果只得到0!
CGFloat percentComplete = [self.pageViewController.transitionCoordinator percentComplete];
答案 0 :(得分:16)
在SWIFT中复制粘贴;)非常适合我
{{1}}
答案 1 :(得分:4)
最后我发现了一个解决方案,即使它可能不是最好的方法:
我首先在scrollview上添加一个观察者,如下所示:
// Get Notified at update of scrollview progress
NSArray *views = self.pageViewController.view.subviews;
UIScrollView* sW = [views objectAtIndex:0];
[sW addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:NULL];
当观察者被召唤时:
NSArray *views = self.pageViewController.view.subviews;
UIScrollView* sW = [views objectAtIndex:0];
CGPoint point = sW.contentOffset;
float percentComplete;
//iPhone 5
if([ [ UIScreen mainScreen ] bounds ].size.height == 568){
percentComplete = fabs(point.x - 568)/568;
} else{
//iphone 4
percentComplete = fabs(point.x - 480)/480;
}
NSLog(@"percentComplete: %f", percentComplete);
我很高兴我发现了这个: - )
答案 2 :(得分:2)
由于我认为滚动的功能会永远存在,但内部实现可能会改变为滚动视图以外的其他内容,我在下面找到了解决方案(我还没有对此进行过多次测试,但仍然)
NSUInteger offset = 0;
UIViewController * firstVisibleViewController;
while([(firstVisibleViewController = [self viewControllerForPage:offset]).view superview] == nil) {
++offset;
}
CGRect rect = [[firstVisibleViewController.view superview] convertRect:firstVisibleViewController.view.frame fromView:self.view];
CGFloat absolutePosition = rect.origin.x / self.view.frame.size.width;
absolutePosition += (CGFloat)offset;
(self是这里的UIPageViewController
,而[-viewControllerForPage:]
是一个在给定页面返回视图控制器的方法)
如果absolutePosition
为0.0f,则显示第一个视图控制器,如果它等于1.0f,则显示第二个,等等......这可以在{ {1}}以及委托方法和/或CADisplayLink
有效地了解UIPanGestureRecognizer
当前进度的状态。
编辑:使其适用于任意数量的视图控制器
答案 3 :(得分:2)
使用此 -
for (UIView *v in self.pageViewController.view.subviews) {
if ([v isKindOfClass:[UIScrollView class]]) {
((UIScrollView *)v).delegate = self;
}
}
实施此协议:-(void)scrollViewDidScroll:(UIScrollView *)scrollView
然后以这种方式使用@ xhist的代码(已修改)
-(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);
}
答案 4 :(得分:1)
虽然Appgix的解决方案一开始似乎有用,但我注意到当用户平移UIPageViewController
时,很快抬起手指然后立即开始再次拖动,而“快照”动画还没有结束然后再次抬起手指(这将再次“快速恢复”),仅在页面视图控制器完成动画时调用scrollViewDidScroll
方法。
对于进度计算,这意味着第二个平移会生成连续值,例如0.11
,0.13
,0.16
,但当滚动视图快照时,下一个进度值将为1.0
,这会导致我的其他滚动视图不同步。
为了解决这个问题,我现在正在听滚动视图的contentOffset
键,在这种情况下它仍然会不断更新。
答案 5 :(得分:0)
基于Appgix解决方案,我直接在我的' UIPageViewController'子类。 (因为我只需要这个)
对于Swift 3:
class MYPageViewControllerSubclass: UIPageViewController, UIScrollViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
for subView in view.subviews {
if subView is UIScrollView {
(subView as! UIScrollView).delegate = self
}
}
}
// MARK: - Scroll View Delegate
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
let point = scrollView.contentOffset
var percentComplete: CGFloat
percentComplete = fabs(point.x - view.frame.size.width)/view.frame.size.width
NSLog("percentComplete: %f", percentComplete)
}
// OTHER CODE GOES HERE...
}
答案 6 :(得分:0)
Swift 4的KVO方法
var myContext = 0
override func viewDidLoad() {
for view in self.view.subviews {
if view is UIScrollView {
view.addObserver(self, forKeyPath: "contentOffset", options: .new, context: &introPagingViewControllerContext)
}
}
}
// MARK: KVO
override func observeValue(forKeyPath keyPath: String?,
of object: Any?,
change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?)
{
guard let change = change else { return }
if context != &myContext {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
return
}
if keyPath == "contentOffset" {
if let contentOffset = change[NSKeyValueChangeKey.newKey] as? CGPoint {
let screenWidth = UIScreen.main.bounds.width
let percent = abs((contentOffset.x - screenWidth) / screenWidth)
print(percent)
}
}
}