我有一个带有中央容器的视图控制器,该容器被翻转以在每一侧显示不同的视图。其中一个视图是表格视图,另一个是我的自定义视图。根据屏幕截图 1,它运行良好。
我的问题是,在我在这个 viewcontroller 上添加了一个子视图(它是一个用于显示帮助屏幕的透明 UIView)然后从 viewcontroller 中删除这个子视图后,当我尝试重新翻转中央视图时,会出现奇怪的结果。两个视图之间似乎仍然存在翻转动画,但正如您从最后 2 个屏幕截图中看到的那样,一个额外的中央表视图就坐在那里。我不能完全解释这一点,所以我希望结合图片,一些代码会有所帮助:
MainPageVC.h
@interface MainPageVC : UIViewController <UITableViewDataSource, UITableViewDelegate>
@end
主页VC.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
自定义帮助文件
@interface CustomHelp : UIView
@end
自定义帮助.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