Pergunta

I've been implementing a simple FlipView in iOS : A UIView that contains two subviews, displaying one at a time, and when you click on it, it flips them. I'm using the following to animate the flipping.

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    @synchronized(self){
        if(!self.flipping){
            self.flipping = YES;
            UIView *toView = self.currentView == self.primaryView ? self.secondaryView : self.primaryView;            
            [UIView transitionFromView:self.currentView toView:toView duration:self.speed options:UIViewAnimationOptionTransitionFlipFromLeft|UIViewAnimationOptionCurveEaseInOut completion:^(BOOL finished) {
                [self.currentView removeFromSuperview];
                self.currentView = toView;
                self.flipping = NO;
            }];                
        }
    }
}

Pretty straight forward, right ?

But what bugs me is that, while the views are flip, the flipped content is darkened. Which shows, against a light background.

Would anyone knows a solution to have the exact same animation, but without the darkening (<= is that even a word ?)

Thanks in advance !

PS : I'm targeting IOS 5 and above.

Foi útil?

Solução 2

I succeeded, getting inspiration in the code I found here http://www.mycodestudio.com/blog/2011/01/10/coreanimation/ (and he, himself, took inspiration from http://www.mentalfaculty.com/mentalfaculty/Blog/Entries/2010/9/22_FLIPPIN_OUT_AT_NSVIEW.html)

Anyway, what I do spin between two views.

- (void)flip{
    @synchronized(self){
        if(!self.flipping){
            self.flipping = YES;

            UIView *bottomView = self.currentView == self.primaryView ? self.secondaryView : self.primaryView;
            CALayer *top = self.currentView.layer;
            CALayer *bot = bottomView.layer;

            CAAnimation *topAnimation = [self flipAnimationWithDuration:self.speed/2.0 forLayerBeginningOnTop:YES scaleFactor:1];
            CAAnimation *bottomAnimation = [self flipAnimationWithDuration:self.speed/2.0 forLayerBeginningOnTop:NO scaleFactor:1];

            CGFloat zDistance = 1500.0f;
            CATransform3D perspective = CATransform3DIdentity;
            perspective.m34 = -1. / zDistance;
            top.transform = perspective;
            bot.transform = perspective;

            topAnimation.delegate = self;
            [CATransaction setCompletionBlock:^{
                [top removeAllAnimations];
                [self.currentView removeFromSuperview];
                self.currentView = bottomView;
                [self addSubview:bottomView];

                [CATransaction setCompletionBlock:^{
                    self.flipping = NO;
                    [bot removeAllAnimations];
                }];
                [CATransaction begin];

                [bot addAnimation:bottomAnimation forKey:@"flip"];

                [CATransaction commit];
            }];
            [CATransaction begin];
            [top addAnimation:topAnimation forKey:@"flip"];

            [CATransaction commit];
        }
    }
}

-(CAAnimation *)flipAnimationWithDuration:(NSTimeInterval)aDuration forLayerBeginningOnTop:(BOOL)beginsOnTop scaleFactor:(CGFloat)scaleFactor
{
    // Rotating halfway (pi radians) around the Y axis gives the appearance of flipping
    CABasicAnimation *flipAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
    CGFloat startValue = beginsOnTop ? 0.0f : M_PI/2;
    CGFloat endValue = beginsOnTop ? -M_PI/2 : 0.0f;
    flipAnimation.fromValue = [NSNumber numberWithDouble:startValue];
    flipAnimation.toValue = [NSNumber numberWithDouble:endValue];

    // Shrinking the view makes it seem to move away from us, for a more natural effect
    // Can also grow the view to make it move out of the screen
    CABasicAnimation *shrinkAnimation = nil;
    if (scaleFactor != 1.0 ) {
        shrinkAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
        shrinkAnimation.toValue = [NSNumber numberWithFloat:scaleFactor];

        // We only have to animate the shrink in one direction, then use autoreverse to "grow"
        shrinkAnimation.duration = aDuration * 0.5;
        shrinkAnimation.autoreverses = YES;
    }

    // Combine the flipping and shrinking into one smooth animation
    CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
    animationGroup.animations = [NSArray arrayWithObjects:flipAnimation, shrinkAnimation, nil];

    // As the edge gets closer to us, it appears to move faster. Simulate this in 2D with an easing function
    animationGroup.timingFunction = [CAMediaTimingFunction functionWithName:beginsOnTop?kCAMediaTimingFunctionEaseIn:kCAMediaTimingFunctionEaseOut];
    animationGroup.duration = aDuration;

    // this really means keep the state of the object at whatever the anim ends at
    // if you don't do this then it reverts back to the original state (e.g. brown layer)
    animationGroup.fillMode = kCAFillModeForwards;
    animationGroup.removedOnCompletion = NO;

    return animationGroup;
}

The two views are named primaryView and secondaryView. You can use any view, (ImageView, text view...)

Outras dicas

I recently had a problem with similar symptoms and I was adding a subview over and over again else where in my code whenever I committed a certain action. Maybe you are doing something similar? When your touches end, are you doing something else to your flipped content? You probably need to remove the subviews being added IF that is your problem.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top