核心动画奇怪的显示在addSubview之后然后removeFromSuperview

时间:2013-07-09 13:42:11

标签: ios core-animation

我有一个带有中央容器的视图控制器,可以翻转以显示每侧的不同视图。其中一个视图是表视图,另一个是我的自定义视图。根据屏幕截图1,它工作得很好。

我的问题是我在这个viewcontroller上添加了一个子视图(它是一个用于显示帮助屏幕的透明UIView),然后从viewcontroller中删除了这个子视图 ,当我尝试重新翻转中心视图时会发生奇怪的结果。两个视图之间似乎仍然存在翻转动画,但正如您从最后2个屏幕截图中看到的那样,还有一个额外的中心表视图。我不能完全解释这一点,所以我希望这些图片的组合,一些代码将有所帮助:

Before the help screen overlay - core animation 'flip' working perfectly enter image description here enter image description here enter image description here

MainPageVC.h

@interface MainPageVC : UIViewController <UITableViewDataSource, UITableViewDelegate>
@end

MainPageVC.m

@interface MainPageVC ()

@property (nonatomic, strong) NSArray *dataArr;

@property (nonatomic, weak) IBOutlet UIView *flipContainerView;
@property (nonatomic, strong) UIView *detailFlipView;
@property (nonatomic, strong) UITableView *listFlipView;

@property (nonatomic) BOOL isTransitioning;
@property (nonatomic) BOOL isFlipped;

@end

@implementation MainPageVC

@synthesize dataArr = _dataArr;

@synthesize flipContainerView = _flipContainerView;
@synthesize detailFlipView = _detailFlipView;
@synthesize listFlipView = _listFlipView;

@synthesize isTransitioning = _isTransitioning;
@synthesize isFlipped = _isFlipped;

- (void)viewDidLoad {
    [super viewDidLoad];

    self.dataArr = [NSArray arrayWithObjects:@"row 1", @"row 2", @"row 3", nil];;
}

- (void)viewDidLayoutSubviews {
    [self setUpCustomViews];
}

- (void)setUpCustomViews {
    self.isFlipped = NO;
    self.isTransitioning = NO;

    CGRect frame = CGRectMake(0, 0, self.flipContainerView.frame.size.width, self.flipContainerView.frame.size.height); 

    self.detailFlipView = [[UIView alloc] initWithFrame:frame];
    UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0,0,50,50)];
    [self.detailFlipView addSubview:customView];

    self.listFlipView = [[UITableView alloc] initWithFrame:frame];
    self.listFlipView.delegate = self;
    self.listFlipView.dataSource = self;

    UIColor *backgroundColour = [UIColor whiteColor];
    CGFloat cornerRadius = 15.0f;
    CGFloat borderWidth = 1.5f;
    UIColor *borderColour = [UIColor colorWithRed:49.0/255.0f green:49.0/255.0f blue:49.0/255.0f alpha:1.0f];

    self.detailFlipView.backgroundColor = backgroundColour;
    self.listFlipView.backgroundColor = backgroundColour;

    self.detailFlipView.layer.cornerRadius = cornerRadius;
    self.listFlipView.layer.cornerRadius = cornerRadius;

    self.detailFlipView.layer.borderWidth = borderWidth;
    self.listFlipView.layer.borderWidth = borderWidth;

    self.detailFlipView.layer.borderColor = [borderColour CGColor];
    self.listFlipView.layer.borderColor = [borderColour CGColor];

    self.detailFlipView.layer.doubleSided = NO;
    self.listFlipView.layer.doubleSided = NO;

    self.listFlipView.layer.masksToBounds = YES;
    self.detailFlipView.layer.masksToBounds = YES;

    [self.flipContainerView addSubview:self.detailFlipView];
    [self.flipContainerView addSubview:self.listFlipView];
}

- (IBAction)changeViewTapped:(UIControl *)sender {
    if (self.isTransitioning) return;

    CALayer *top = self.listFlipView.layer;
    CALayer *bottom = self.detailFlipView.layer;

    if (self.isFlipped) {
        top = self.detailFlipView.layer;
        bottom = self.listFlipView.layer;
    }

    CAAnimation *topAnimation = [self flipAnimationWithDuration:0.6f forLayerBeginningOnTop:YES scaleFactor:1.2f];
    CAAnimation *bottomAnimation = [self flipAnimationWithDuration:0.6f forLayerBeginningOnTop:NO scaleFactor:1.2f];

    CGFloat zDistance = 1000.0f;
    CATransform3D perspective = CATransform3DIdentity;
    perspective.m34 = -1. / zDistance;
    top.transform = perspective;
    bottom.transform = perspective;

    topAnimation.delegate = self;
    [CATransaction begin];
    [top addAnimation:topAnimation forKey:@"flip"];
    [bottom addAnimation:bottomAnimation forKey:@"flip"];

    CABasicAnimation *colorAnimation = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
    colorAnimation.toValue = (id)[UIColor colorWithRed:27.0/255.0f green:47.0/255.0f blue:87.0/255.0f alpha:1.0f].CGColor;
    [self.bannerButtonImageView.layer addAnimation:colorAnimation forKey:@"colorAnimation"];

    [CATransaction commit];
}

-(CAAnimation *)flipAnimationWithDuration:(NSTimeInterval)aDuration forLayerBeginningOnTop:(BOOL)beginsOnTop scaleFactor:(CGFloat)scaleFactor {
    self.isTransitioning = YES;
    CABasicAnimation *flipAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
    CGFloat startValue = beginsOnTop ? 0.0f : M_PI;
    CGFloat endValue = beginsOnTop ? -M_PI : 0.0f;
    flipAnimation.fromValue = [NSNumber numberWithDouble:startValue];
    flipAnimation.toValue = [NSNumber numberWithDouble:endValue];

    CABasicAnimation *shrinkAnimation = nil;
    if (scaleFactor != 1.0f ) {
        shrinkAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
        shrinkAnimation.toValue = [NSNumber numberWithFloat:scaleFactor];

        shrinkAnimation.duration = aDuration * 0.5;
        shrinkAnimation.autoreverses = YES;
    }

    CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
    animationGroup.animations = [NSArray arrayWithObjects:flipAnimation, shrinkAnimation, nil];

    animationGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    animationGroup.duration = aDuration;

    animationGroup.fillMode = kCAFillModeForwards;
    animationGroup.removedOnCompletion = NO;

    return animationGroup;
}

-(void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag {
    self.isFlipped = !self.isFlipped;
    self.isTransitioning = NO;
}

...USUAL UITABLEVIEW METHODS

- (void)showHelpScreen {
    CustomHelp *helpView = [[CustomHelp alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
    [self.view addSubview:helpView];
}
@end

CustomHelp.h

@interface CustomHelp : UIView
@end

CustomHelp.m

@implementation CustomHelp

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        UIView *test = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 50, 100)];
        test.backgroundColor = [UIColor redColor];
        [self addSubview:test];

        UITapGestureRecognizer* singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap)];

        singleTap.numberOfTapsRequired = 1;
        singleTap.numberOfTouchesRequired = 1;
        [self addGestureRecognizer: singleTap];
    }
    return self;
}

- (void)handleSingleTap {
    [UIView animateWithDuration:0.5
        animations:^{ self.alpha = 0.0;}
        completion:^(BOOL finished){
            [self removeFromSuperview];
        }];
}

@end

1 个答案:

答案 0 :(得分:2)

添加评论作为答案。

我唯一的建议是在setUpCustomViews函数中添加if(!self.listFlipView)if(!self.detailFlipView)到视图创建。可以多次调用该函数,从而在不删除前一个窗口的情况下向窗口添加多个视图。