Ios UIView垂直翻转动画

Ios UIView垂直翻转动画,ios,uiview,core-animation,Ios,Uiview,Core Animation,我有一个iOS UIView,带有UIViewAnimationTransitionFlipFromRight。我需要它垂直翻转。页面卷曲转换无法剪切它。我想这需要一些定制的东西 有什么想法吗?只要使用核心动画变换编写自己的翻转方法即可 - (void)verticalFlip{ [UIView animateWithDuration:someDuration delay:someDelay animations:^{ yourView.layer.transform =

我有一个iOS UIView,带有
UIViewAnimationTransitionFlipFromRight
。我需要它垂直翻转。页面卷曲转换无法剪切它。我想这需要一些定制的东西


有什么想法吗?

只要使用核心动画变换编写自己的翻转方法即可

- (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
    }];
}
如果要使用
M_PI
符号,请确保添加并包含了核心动画库/框架,并且还包含了
math.h

编辑:

  -(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];
要使其在翻转一半时基本上“更改”视图,请执行以下操作:

- (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
        }];
    }];
}
这也可以起作用:

- (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
    }];
}

干杯

布伦顿的代码对我不起作用,所以我对苹果的文档做了更多的挖掘,并进行了水平翻转:

- (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;
                                   }
                              }
    ];
}

通过将选项从
uiviewmanimationoptionTransitionFlipfromright:uiviewmanimationoptionTransitionFlipfromleft
更改为
uiviewmanimationoptionTransitionFlipfromtop:uiviewmanimationoptionTransitionFlipfrombottom
,可以进行垂直翻转


工作起来很有魅力。

从iOS 5.0开始,无需编写自己的核心动画转换来进行垂直翻转。只要使用UIKit的转换,所有这些东西就变成了一个方法调用

它们的行为与
uiviewmanimationoptiontransitionflipfromlight
uiviewmanimationoptiontransitionflipfromlight
(自iOS 2.0以来一直存在)类似

用法示例:

[UIView transitionFromView:viewToReplace
                    toView:replacementView
                  duration:1
                   options:UIViewAnimationOptionTransitionFlipFromBottom
                completion:nil];
上述代码将垂直翻转
视图的superview以替换
。在动画的中间点,当superview垂直于屏幕,因此不可见时,
viewToReplace
replacementView
替换

就这么简单

[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];

您可以在翻转视图时进行任何修改,这里我更改了背景颜色

UIViewAnimationOptionTransitionFlipFromTop易于使用,但我们无法使用UIViewAnimationOptionTransitionFlipFromTop创建交互式过渡。我们需要改变层的变换来创建一个交互式转换

仅使用CATTransferM3dMake创建变换旋转是不够的,没有灯光效果,没有透视。我写了一个示例来添加这些效果。您可以轻松地将其更改为交互式过渡

演示:

示例代码:

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和sideBView是containerView的子视图


containerView设置为黑色背景。

要切换到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 4.0版100%工作解决方案

// 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 = UIViewAnimationOptions()
    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
    })
}
函数的调用:

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

最佳做法是创建
UIView
扩展并将此函数保留到该扩展,以便任何
UIView
子对象都可以访问它。此解决方案也可以使用completionBlock编写。

Swift 5版本的@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
    })
}

我已经让视图翻转,但我需要某种方式显示视图的“背面”。有没有一种方法可以在动画进行到一半时隐藏其子视图,从而模拟视图背面为“空”视图?对于三维变换,您需要执行视图.layer.transform而不是视图.transform完成块应该有一个bool。完成:^(BOOL finished){您还应该在“编辑:”之后的代码中使用call+(void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay选项:(UIViewAnimationOptions)options动画:(void(^)(void))animations completion:(void(^)(BOOL finished))completion标记-选项:原始注释中缺少参数。您应该在2*M_PI上旋转,以避免在秒代码块中翻转的后半部分中看到上下颠倒。这不是垂直翻转。这是系统提供的水平翻转。下翻转有什么问题?此代码比其他示例更短更清晰。是否存在隐藏的问题a?一定有人投了反对票b/c最初的问题是关于垂直翻转,而不是水平翻转。苹果提供的UIViewAnimationOptionTransition常量中的水平翻转更容易b/c。因此,提问者最初关于垂直过渡效果的查询。您可以通过更改…选项:IsDetailView?UIViewAnimationOptionTransitionFlipFromRight:UIViewAnimationOptionTransitionFlipFromLeft)
…选项:IsDetailView?UIViewAnimationOptionTransitionFlipFromTop:UIViewAnimationOptionTransitionFlipFromBottom)
还有一件事。如果尝试翻转子视图和您不希望超级视图翻转。请将两个子视图放在一个容器视图中。这样它就不会翻转您的全屏视图!注意:在调用动画之前,将两个视图都插入到超级视图中。“viewToReplace”必须位于“replacementView”的前面。两个视图都必须设置为hidden=false。@Artjom您声称的与我的经验不同。在调用
transitionFromView:…
之前,无需将
replacementView
插入superview,这对我来说效果非常好。也许还有一些不明显相关的事情,我们也正在以不同的方式进行我们观察到的不同之处?您能提供一个示例项目来演示您所描述的内容吗?在我的例子中,两个视图都是从nib初始化为类成员的。但是如果不在翻转超级视图中同时插入这两个视图,您的方法将不起作用。只需将视图设置为属性,然后只插入一个视图,翻转将处理替换afterwards-1因为a)这是一个水平翻转,b)我不认为这增加了我的答案还没有提供的任何新内容。这个动画有点问题。正如你所看到的,在旋转的下半部分,透视图被完全移除,看起来很奇怪。谢谢@C0mrade,你节省了我的时间。有办法摆脱黑暗吗翻转时发生的视图的细节?我使用了这个