开发者

UIView vertical flip animation

开发者 https://www.devze.com 2023-02-18 19:42 出处:网络
I have an iOS UIView with UIViewAnimationTransitionFlipFromRight. I need it to flip vertically though. The page curl transition won\'t cut it. 开发者_如何学GoI assume this will require something custo

I have an iOS UIView with UIViewAnimationTransitionFlipFromRight. I need it to flip vertically though. The page curl transition won't cut it. 开发者_如何学GoI assume this will require something custom.

Any ideas?


Just write your own method for the flip using Core Animation Transforms.

- (void)verticalFlip{
    [UIView animateWithDuration:someDuration delay:someDelay animations:^{
        yourView.layer.transform = CATransform3DMakeRotation(M_PI,1.0,0.0,0.0);
    } completion:^{
        // code to be executed when flip is completed
    }];
}

Make sure you have the Core Animation libraries/frameworks added and included and also have included math.h if you want to use the M_PI notation.

EDIT:

To have it essentially "change" the view when it's halfway flipped do something like this:

- (void)verticalFlip{
    [UIView animateWithDuration:someDuration delay:someDelay animations:^{
        yourView.layer.transform = CATransform3DMakeRotation(M_PI_2,1.0,0.0,0.0); //flip halfway
    } completion:^{
        while ([yourView.subviews count] > 0)
            [[yourView.subviews lastObject] removeFromSuperview]; // remove all subviews
        // Add your new views here 
        [UIView animateWithDuration:someDuration delay:someDelay animations:^{
            yourView.layer.transform = CATransform3DMakeRotation(M_PI,1.0,0.0,0.0); //finish the flip
        } completion:^{
            // Flip completion code here
        }];
    }];
}

This could also work:

- (void)verticalFlip{

    // Do the first half of the flip
    [UIView animateWithDuration:someDuration delay:someDelay animations:^{
        yourView.layer.transform = CATransform3DMakeRotation(M_PI_2,1.0,0.0,0.0); //flip halfway
    } completion:^{
        while ([yourView.subviews count] > 0)
            [[yourView.subviews lastObject] removeFromSuperview]; // remove all subviews
        // Add your new views here 
    }];

    // After a delay equal to the duration+delay of the first half of the flip, complete the flip
    [UIView animateWithDuration:someDuration delay:durationOfFirstAnimation animations:^{
        yourView.layer.transform = CATransform3DMakeRotation(M_PI,1.0,0.0,0.0); //finish the flip
    } completion:^{
        // Flip completion code here
    }];
}

Cheers.


As of iOS 5.0, there's no need to write your own Core Animation transformation to do vertical flips. Just use UIKit's UIViewAnimationOptionTransitionFlipFromTop and UIViewAnimationOptionTransitionFlipFromBottom transitions, and all this stuff becomes a single method call.

These behave analagously to UIViewAnimationOptionTransitionFlipFromLeft and UIViewAnimationOptionTransitionFlipFromRight (which have been around since iOS 2.0).

Example usage:

[UIView transitionFromView:viewToReplace
                    toView:replacementView
                  duration:1
                   options:UIViewAnimationOptionTransitionFlipFromBottom
                completion:nil];

The above code will vertically flip the superview of viewToReplace. At the halfway point in the animation, at the instant when the superview is perpendicular to the screen and thus invisible, viewToReplace gets replaced by replacementView.

It's that easy.


The code from Brenton didn't work for me so I did a little more digging through the apple docs and found this piece of code for an horizontal flip:

- (IBAction)toggleMainViews:(id)sender {
    [UIView transitionFromView:(displayingPrimary ? primaryView : secondaryView)
                        toView:(displayingPrimary ? secondaryView : primaryView)
                      duration:1.0
                       options:(displayingPrimary ? 
                                    UIViewAnimationOptionTransitionFlipFromRight :
                                    UIViewAnimationOptionTransitionFlipFromLeft)
                    completion:^(BOOL finished) {
                                   if (finished) {
                                       displayingPrimary = !displayingPrimary;
                                   }
                              }
    ];
}

You can do a vertical flip by changing the options from UIViewAnimationOptionTransitionFlipFromRight : UIViewAnimationOptionTransitionFlipFromLeft to UIViewAnimationOptionTransitionFlipFromTop : UIViewAnimationOptionTransitionFlipFromBottom.

Worked like a charm.


UIViewAnimationOptionTransitionFlipFromTop is easy to use, but we can not create an interactive transition using UIViewAnimationOptionTransitionFlipFromTop. We need change layer’s transform to create an interactive transition.

Just create a transform using CATransform3DMakeRotation is not enough, no light effect, no perspective. I write an sample to add these effect. You can change it to an interactive transition easily.

Demo:

UIView vertical flip animation

Sample code:

CALayer *sideALayer = sideAView.layer;
CALayer *sideBLayer = sideBView.layer;
CALayer *containerLayer = containerView.layer;

sideALayer.opacity = 1;
sideBLayer.opacity = 0;
sideBLayer.transform = CATransform3DMakeRotation(M_PI, 0, 1, 0);
containerLayer.transform = CATransform3DIdentity;

CATransform3D perspectiveTransform = CATransform3DIdentity;
perspectiveTransform.m34 = -1.0 / containerViewWidth;
[UIView animateKeyframesWithDuration:1 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:^{

    [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:0.5 animations:^{
        sideALayer.opacity = 0;
        containerLayer.transform = CATransform3DConcat(perspectiveTransform,CATransform3DMakeRotation(M_PI_2, 0, 1, 0));
    }];
    [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.5 animations:^{
        sideBLayer.opacity = 1;
        containerLayer.transform = CATransform3DConcat(perspectiveTransform, CATransform3DMakeRotation(M_PI, 0, 1, 0));
    }];
} completion:nil];

sideAView and sideBView are subviews of containerView.

The containerView is set a black background.


Swift 4.0 Version 100% Working Solution

// view1: represents view which should be hidden and from which we are starting
// view2: represents view which is second view or behind of view1
// isReverse: default if false, but if we need reverse animation we pass true and it
// will Flip from Left

func flipTransition (with view1: UIView, view2: UIView, isReverse: Bool = false) {
    var transitionOptions = UIView.AnimationOptions() // Swift 4.2
    transitionOptions = isReverse ? [.transitionFlipFromLeft] : [.transitionFlipFromRight] // options for transition
    
    // animation durations are equal so while first will finish, second will start
    // below example could be done also using completion block.
    
    UIView.transition(with: view1, duration: 1.5, options: transitionOptions, animations: {
        view1.isHidden = true
    })
    
    UIView.transition(with: view2, duration: 1.5, options: transitionOptions, animations: {
        view2.isHidden = false
    })
}

Call of the function:

anim.flipTransition(with: viewOne, view2: viewTwo)
anim.flipTransition(with: viewTwo, view2: viewOne, isReverse: true)

Best practice will be to create UIView extension and hold this function to that extension so it will be accessible to any UIView child object. This solution also can be written using completionBlock.


To flip into UIView:

  -(void) goToSeconVC
 {
  SecondVC *secondVCObj = [[SecondVC alloc] init];
  [UIView beginAnimation: @”View Flip” context: nil];
  [UIView setAnimationDuration: 1.0];
  [UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
  [UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight forView: self.navigationController.view cache: NO];
  [sef.navigationController pushViewController: seconVCObj animated: YES];
  [UIView commitAnimation];
 }
**To flip into a view controller:**
          viewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
         [self presentViewController:viewController animated:YES completion:nil];
**To flip out of it:**

[self dismissViewControllerAnimated:YES completion:nil];


Swift 5 version of @C0mrade

func flipTransition (with view1: UIView, view2: UIView, isReverse: Bool = false) {
    var transitionOptions = UIView.AnimationOptions()
    transitionOptions = isReverse ? [.transitionFlipFromLeft] : [.transitionFlipFromRight]

    UIView.transition(with: view1, duration: 1.5, options: transitionOptions, animations: {
        view1.isHidden = true
    })

    UIView.transition(with: view2, duration: 1.5, options: transitionOptions, animations: {
        view2.isHidden = false
    })
}


[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.75];
// checks to see if the view is attached
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight
                       forView:flipLabel
                         cache:YES];

 flipLabel.backgroundColor = [UIColor yellowColor];



[UIView commitAnimations];

You can make any modification which you want while flipping view, Here I have change the background color

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号