Change the speed of setContentOffset:animated:?
[UIView animateWithDuration:2.0 animations:^{
scrollView.contentOffset = CGPointMake(x, y);
}];
It works.
Setting the content offset directly did not work for me. However, wrapping setContentOffset(offset, animated: false)
inside an animation block did the trick.
UIView.animate(withDuration: 0.5, animations: {
self.tableView.setContentOffset(
CGPoint(x: 0, y: yOffset), animated: false)
})
I've taken nacho4d's answer and implemented the code, so I thought it would be helpful for other people coming to this question to see working code:
I added member variables to my class:
CGPoint startOffset;
CGPoint destinationOffset;
NSDate *startTime;
NSTimer *timer;
and properties:
@property (nonatomic, retain) NSDate *startTime;
@property (nonatomic, retain) NSTimer *timer;
and a timer callback:
- (void) animateScroll:(NSTimer *)timerParam
{
const NSTimeInterval duration = 0.2;
NSTimeInterval timeRunning = -[startTime timeIntervalSinceNow];
if (timeRunning >= duration)
{
[self setContentOffset:destinationOffset animated:NO];
[timer invalidate];
timer = nil;
return;
}
CGPoint offset = [self contentOffset];
offset.x = startOffset.x +
(destinationOffset.x - startOffset.x) * timeRunning / duration;
[self setContentOffset:offset animated:NO];
}
then:
- (void) doAnimatedScrollTo:(CGPoint)offset
{
self.startTime = [NSDate date];
startOffset = self.contentOffset;
destinationOffset = offset;
if (!timer)
{
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.01
target:self
selector:@selector(animateScroll:)
userInfo:nil
repeats:YES];
}
}
you'd also need timer cleanup in the dealloc method. Since the timer will retain a reference to the target (self) and self has a reference to the timer, some cleanup code to cancel/destroy the timer in viewWillDisappear is likely to be a good idea too.
Any comments on the above or suggestions for improvement would be most welcome, but it is working very well with me, and solves other issues I was having with setContentOffset:animated:.