简体   繁体   English

无法在scrollViewDidEndDragging中设置setContentOffset

[英]Unable to setContentOffset in scrollViewDidEndDragging

I am attempting to modify the contentOffset of my scroll within the following delegate method: 我试图在以下委托方法中修改我的滚动的contentOffset:

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate

I have tried both of the following: 我尝试了以下两种方法:

[UIView animateWithDuration:.2 animations:^ {
   [scrollView setContentOffset:CGPointZero animated:NO];
}];

and

[UIView animateWithDuration:.2 animations:^ {
   CGRect svBounds = self.bounds;
   svBounds.origin.y = 0;
   self.bounds = svBounds; 
}];

The problem is that although this changes the offset right away (proven by logs after the animation is complete), it doesn't change the visible scroll location. 问题是虽然这会立即改变偏移(在动画完成后通过日志证明),但它不会改变可见的滚动位置。 This is further proven by subsequent delegate methods of my scroll view which indicate that the bounds have indeed not changed at all. 我的滚动视图的后续委托方法进一步证明了这一点,它表明边界确实没有改变。 Meaning that the y location is not 0. 意味着y位置不为0。

Is it forbidden to change the content offset in this particular delegate method? 是否禁止在此特定委托方法中更改内容偏移量? If so, when is it possible for me to change the offset? 如果是这样,我什么时候可以改变偏移? I'm trying to perform an animation of returning the visible scroll area to the top once the user finishes dragging (after a certain amount). 我正在尝试执行动画,一旦用户完成拖动(在一定量之后),将可见滚动区域返回到顶部。

Thanks! 谢谢!

what i did eventually is dispatching again to the main queue. 我最终做的是再次调度到主队列。 meaning: 含义:

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
NSLog(@"END DRAG");
CGFloat yVelocity = [scrollView.panGestureRecognizer velocityInView:scrollView].y;
if (yVelocity < 0) {
    NSLog(@"Up");
} else {
    NSLog(@"Down");
}

if (yVelocity < 0 && scrollView.contentOffset.y < -100 && scrollView.contentOffset.y > -200) //UP - Hide
{
    NSLog(@"hiding");
    dispatch_async(dispatch_get_main_queue(), ^{
        [scrollView setContentOffset:CGPointMake(0, 0) animated:YES];
    });
}
else if (yVelocity > 0 && scrollView.contentOffset.y < -100) //DOWN - Show
{
    NSLog(@"showing");
    dispatch_async(dispatch_get_main_queue(), ^{
        [scrollView setContentOffset:CGPointMake(0, -300) animated:YES];
    });
}

}

and it actually works :-) 它确实有效:-)

You should "nil" your scrollView delegate before animation, set content offset in scrollViewDidEndDragging:willDecelerate: will cause repeat delegation. 你应该在动画之前“nil”你的scrollView委托,在scrollViewDidEndDragging:willDecelerate:设置内容偏移scrollViewDidEndDragging:willDecelerate:将导致重复委派。

self.scrollView.delegate = nil;
[self.scrollView setContentOffset:CGPointMake(x, y) animated:YES];
self.scrollView.delegate = self;

Depending on the effect you are trying to achieve, you may have more luck with this delegate method: 根据您尝试实现的效果,您可以通过此委托方法获得更多好运:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset

You can choose what target content offset you want to use for the scroll view to decelerate to once the user stops dragging. 您可以选择要用于滚动视图的目标内容偏移量,以便在用户停止拖动时减速。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM