I am currently building a UI plugin. This plugin has 2 imageViews with one on top of another.
When the user swipes on the screen: If the swipe is greater than a threshold, the front imageView will leave the screen in the same direction as the swipe and then appear behind the back imageView.
So we plan to use this for a queue of images. After a successful swipe, the front imageView will leave the screen, then center behind the backImageView (which is now the front), and then it will change the image within.
When there are no more images, I put up a spinner to indicate that we are downloading more images from the server.
We are running into one bug that we couldn't explain ourselves - when we add the spinner into our view, our animation malfunctions.
The swiped imageView no longer leaves the screen but returns to its original position.
We are extremely puzzled by this and confirmed that
[self.view addSubview:spinner];
will result in an unexpected behavior for our animation.
Attached please fine the move method:
- (void)move:(UIPanGestureRecognizer *)sender {
CGPoint translatedPoint = [sender translationInView:self.frontView];
if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {
_firstX = self.frontView.center.x;
_firstY = self.frontView.center.y;
}
translatedPoint = CGPointMake(_firstX+translatedPoint.x, _firstY+translatedPoint.y);
[self.frontView setCenter:translatedPoint];
if ([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
// Calculate the if the x-movement is greater than a threshold
float xTravelled = 0;
if (self.frontView.center.x > _firstX)
xTravelled = self.frontView.center.x - _firstX;
else
xTravelled = _firstX - self.frontView.center.x;
// Only move if xTravelled is greater than threshold
if (xTravelled > self.frontView.window.frame.size.width / 3) {
NSLog(@"Swipe detected, currentIndex:%d", currentIndex);
// Lock view from panning until animation is finished.
self.view.userInteractionEnabled = NO;
float newXPosition;
if (self.frontView.center.x > _firstX) {
newXPosition = (float) self.view.frame.size.width * 2;
} else {
newXPosition = (float) -2 * self.view.frame.size.width;
}
// We should trigger a fetch as soon as the back image is empty.
if (![self getBackView].image) {
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
//[self fetchComplete];
[spinner stopAnimating];
[spinner removeFromSuperview];
self.view.userInteractionEnabled = YES;
});
// Pop up spinner if necessary
if (![spinner isAnimating]) {
self.view.userInteractionEnabled = NO;
[spinner setCenter:CGPointMake(_firstX, _firstY)];
[spinner startAnimating];
/* THIS BREAKS OUR ANIMATION - Enable it to see
[self.view addSubview:spinner];
*/
}
}
// Animate the rest of the swipe
[UIView \
animateWithDuration:0.5f delay:0.0f options:UIViewAnimationOptionTransitionNone
animations:^{
// Use smooth animation to move the top image out of the way
[self.frontView setCenter:CGPointMake(newXPosition, self.frontView.center.y)];
}
completion:^(BOOL finished){
// Set it to be physically behind the back image
[self.view sendSubviewToBack:self.frontView];
//[self.frontView setCenter:CGPointMake(_firstX, _firstY)]; // why not necessary??
// Now change the picture
UIImage *next = [self nextImage];
self.frontView.image = next;
// update self.top to reference the new back image
self.frontView = [self getBackView];
// Do not override spinner's block
if (![spinner isAnimating])
self.view.userInteractionEnabled = YES;
}];
} else {
NSLog(@"Swipe NOT detected");
[UIView \
animateWithDuration:0.5f delay:0.0f options:UIViewAnimationOptionAllowUserInteraction
animations:^{
[self.frontView setCenter:CGPointMake(_firstX, _firstY)];
} completion:^(BOOL finished) {
self.view.userInteractionEnabled = YES;
}];
}
}
I understand that this is rather lenghty, but I have isolated this bug into a sample project that you can download and run on your computer. This sample project is here: http://bit.ly/WO4cEI
We suspect that adding a subview to self.view is causing [self.view sendSubviewToBack:self.frontView] to fail. But we are not sure why this is causing our animation to fail either.
Thanks for the help!!
EDIT
@user2113425's recommendation fixed this problem!!