Is there any way to specify a duration for the animation of [UIScrollView zoomToRect:zoomRect animated:YES]
?
At the moment it's either fast animated:YES
or instant animated:NO
.
I'd like to specify a duration, eg [UIScrollView setAnimationDuration:2]
; or something similar.
Thanks in advance!
Use the UIView's animations.
It's a bit long to explain, so I hope this little example will clear things up a bit.
Look at the documantation for further instructions
[UIView beginAnimations: nil context: NULL];
[UIView setAnimationDuration: 2];
[UIView setAnimationDelegate: self];
[UIView setAnimationDidStopSelector: @selector(revertToOriginalDidStop:finished:context:)];
expandedView.frame = prevFrame;
[UIView commitAnimations];
It's from a project I'm currently working on so it's a bit specific, but I hope you can see the basics.
I've had luck with this method in a UIScrollView subclass:
- (void)zoomToRect:(CGRect)rect duration:(NSTimeInterval)duration
{
[self setZoomLimitsForSize:rect.size];
if (duration > 0.0f) {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:duration];
}
[self zoomToRect:rect animated:NO];
if (duration > 0.0f)
[UIView commitAnimations];
[self zoomToRect:rect animated:(duration > 0.0f)];
}
It's kinda cheating, but it seems to mostly work. Occasionally it does fail, but I don't know why. In this case it just reverts to the default animation speed.
Actually these answers are really close to what I ended up using but I'll post mine separately since it is different. Basically the zoomToRect does not work correctly if the destination zoomScale is the same as the current one.
You could try to scrollToRect but I did not have any luck with that.
Instead just use the contentOffset and set it to the zoomRect.origin and nest that in the animation block.
[UIView animateWithDuration:duration
delay:0.f
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
if (sameZoomScale) {
CGFloat offsetX = zoomRect.origin.x * fitScale;
CGFloat offsetY = zoomRect.origin.y * fitScale;
[self.imageScrollView setContentOffset:CGPointMake(offsetX, offsetY)];
}
else {
[self.imageScrollView zoomToRect:zoomRect
animated:NO];
}
}
completion:nil];