繁体   English   中英

iOS:如何为两个UIView之间的翻转设置动画?

[英]iOS: How to animate a flip between two UIViews?

我正在尝试为UIButton实例和UIImageView实例之间的翻转效果设置动画。 基本上,这是一种“翻转纸牌”效果,一侧(UIImageView)只是一种不错的模式,翻转时,它应该显示带有一些文本的UIButton。

我的代码存在以下问题:

  • 翻转后不显示UIButton子视图的文本
  • 阴影在翻转动画期间消失

这是目标的直观表示:

在此处输入图片说明

在这里,您可以下载非常简单的示例应用程序。

有什么建议如何解决上述两个问题?

我真的没有主意-任何帮助,我们将不胜感激!

这是标头代码:

#import <UIKit/UIKit.h>

@interface CardView : UIControl

@property (nonatomic) BOOL isFrontSide;

- (void)setupView;
- (void)turnCard:(BOOL)inShow withAnimationCompletion:(void (^)(BOOL inFinished))inCompletion;

@end

这是实现代码:

#import "CardView.h"
#import "UIView+Extension.h"
#import <QuartzCore/QuartzCore.h>

#define kAllControlStates (UIControlStateNormal | UIControlStateHighlighted | UIControlStateDisabled| UIControlStateSelected)

@interface CardView()

@end

@implementation CardView

- (void)setupView {

    [self styleViewWithRoundedEdges:YES shadowed:YES];

    UIImageView *theBackView = [[UIImageView alloc] initWithFrame:self.bounds];
    theBackView.image = [UIImage imageNamed:@"pattern.png"];
    theBackView.hidden = NO;
    theBackView.userInteractionEnabled = NO;
    [theBackView styleViewWithRoundedEdges:YES shadowed:NO];
    [self addSubview:theBackView];

    UIButton *theFrontView = [[UIButton alloc] initWithFrame:self.bounds];
    [theFrontView setTitle:@"Push me !" forState:kAllControlStates];
    theFrontView.hidden = YES;
    theFrontView.userInteractionEnabled = NO;
    [theFrontView styleViewWithRoundedEdges:YES shadowed:NO];
    [self addSubview:theFrontView];

}

- (void)turnCard:(BOOL)inShow withAnimationCompletion:(void (^)(BOOL inFinished))inCompletion { 
    [UIView transitionWithView:self duration:0.75 
                       options:inShow ? UIViewAnimationOptionTransitionFlipFromLeft : UIViewAnimationOptionTransitionFlipFromRight
                    animations:^{
                        [(self.subviews)[0] setHidden:inShow];      // UIImage
                        [(self.subviews)[1] setHidden:!inShow];     // UIButton
                    } 
                    completion:inCompletion];
}

@end

这是在视觉上装饰我的视图的类别:

#import "UIView+Extension.h"

@implementation UIView (Extension)

- (void)styleViewWithRoundedEdges:(BOOL)rounded shadowed:(BOOL)shadowed {
    [self styleViewWithRoundedEdges:rounded shadowed:shadowed rasterized:YES];
}

- (void)styleViewWithRoundedEdges:(BOOL)rounded shadowed:(BOOL)shadowed rasterized:(BOOL)rasterized {
    if (rounded) {
        self.layer.cornerRadius = 3.0;
    }
    if (shadowed) {
        self.layer.shadowColor = [UIColor blackColor].CGColor;
        self.layer.shadowOffset = CGSizeMake(2.0, 2.0);
        self.layer.shadowOpacity = 0.25;
        self.layer.shadowRadius = 1.0;
        if(rasterized) {
            self.layer.shouldRasterize = YES;
            self.layer.rasterizationScale = UIScreen.mainScreen.scale;
        }
    }
}

@end

这是我的工作解决方案,带有阴影,圆角并且没有性能问题:

调用[self.yourUICardButtonInstance setupWithImage:[UIImage imageNamed:@"your-image.png"]]; 在视图控制器的viewDidLayoutSubviews回调中。

标题:

//
//  UICardButton.h
//  CardFlipDemo
//
//  Created by Nicolas Baumgardt on 25/08/15.
//  Copyright (c) 2015 Nicolas Baumgardt. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface UICardButton : UIButton

- (void)setupWithImage:(UIImage*)backside;

- (void)flip;
- (void)flipFrontside;
- (void)flipBackside;

@end

执行:

//
//  UICardButton.m
//  CardFlipDemo
//
//  Created by Nicolas Baumgardt on 25/08/15.
//  Copyright (c) 2015 Nicolas Baumgardt. All rights reserved.
//

#import "UICardButton.h"

@interface UICardButton ()

@property (nonatomic) BOOL setup;

@property (nonatomic, strong) NSString* text;
@property (nonatomic, strong) UIImageView* subview;

@property (nonatomic) BOOL IBInspectable styled;
@property (nonatomic) BOOL IBInspectable frontside;

@end

@implementation UICardButton

- (void)setupWithImage:(UIImage*)backside {
    if (!self.setup) {
        // cache properties
        self.text = self.currentTitle;
        self.subview = [[UIImageView alloc] initWithFrame:self.bounds];
        [self.subview setImage:backside];
        // initialize card side
        if (self.frontside) {
            // frontside: with text
            self.layer.transform = CATransform3DMakeRotation(0.0, 0.0, 1.0, 0.0);
            [self setAttributedTitle:nil forState:UIControlStateNormal];
            [self setTitle:self.text forState:UIControlStateNormal];
        } else {
            // backside: with image
            self.layer.transform = CATransform3DMakeRotation(M_PI, 0.0, 1.0, 0.0);
            [self addSubview:self.subview];
            [self setAttributedTitle:nil forState:UIControlStateNormal];
            [self setTitle:@"" forState:UIControlStateNormal];
        }
        // add a shadow by wrapping the button into a container and add rounded corners
        if (self.styled) {
            // add a shadow
            self.layer.shadowColor = [UIColor blackColor].CGColor;
            self.layer.shadowOffset = self.frontside ? CGSizeMake(2.0, 2.0) : CGSizeMake(-2.0, 2.0);
            self.layer.shadowOpacity = 0.25;
            self.layer.shadowRadius = 1.0;
            self.layer.cornerRadius = 3.0;
            self.layer.masksToBounds = NO;
            // clip card image
            self.subview.layer.masksToBounds = YES;
            self.subview.layer.cornerRadius = 3.0;
            // INFO: rasterization sometimes causes flickering, but enormous performance boost !
            self.layer.shouldRasterize = YES;
            self.layer.rasterizationScale = UIScreen.mainScreen.scale;
        }
        self.setup = YES;
    }
}

- (void)flip {
    if (self.frontside) {
        [self flipBackside];
    } else {
        [self flipFrontside];
    }
    self.frontside = !self.frontside;
}

- (void)flipFrontside {
    self.userInteractionEnabled = NO;
    [UIView animateWithDuration:0.25 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
        self.layer.transform = CATransform3DMakeRotation(M_PI_2, 0.0, 1.0, 0.0);
    } completion:^(BOOL finished) {
        [self.subview removeFromSuperview];
        [self setAttributedTitle:nil forState:UIControlStateNormal];
        [self setTitle:self.text forState:UIControlStateNormal];
        self.layer.shadowOffset = CGSizeMake(2.0, 2.0);
        [UIView animateWithDuration:0.25 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
            self.layer.transform = CATransform3DMakeRotation(0.0, 0.0, 1.0, 0.0);
        } completion:^(BOOL finished) {
            self.userInteractionEnabled = YES;
        }];
    }];
}

- (void)flipBackside {
    self.userInteractionEnabled = NO;
    [UIView animateWithDuration:0.25 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
        self.layer.transform = CATransform3DMakeRotation(M_PI_2, 0.0, 1.0, 0.0);
    } completion:^(BOOL finished) {
        [self addSubview:self.subview];
        [self setAttributedTitle:nil forState:UIControlStateNormal];
        [self setTitle:@"" forState:UIControlStateNormal];
        self.layer.shadowOffset = CGSizeMake(-2.0, 2.0);
        [UIView animateWithDuration:0.25 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
            self.layer.transform = CATransform3DMakeRotation(M_PI, 0.0, 1.0, 0.0);
        } completion:^(BOOL finished) {
            self.userInteractionEnabled = YES;
        }];
    }];
}

@end

尝试使用:

    [UIView transitionFromView:self.subviews[0] toView:self.subviews[1] duration:0.5 UIViewAnimationOptionTransitionFlipFromLeft | UIViewAnimationOptionShowHideTransitionViews completion:^(BOOL finished) {
    }];

这应该工作

[UIView transitionFromView:self.subviews[0] toView:self.subviews[1] duration:0.5 UIViewAnimationOptionTransitionFlipFromLeft | UIViewAnimationOptionShowHideTransitionViews completion:^(BOOL finished) {
}];

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM