我会将 Springboard 分成几个视图,其中每个视图都是一行图标。
如果单击文件夹图标,我会为所有以下视图设置动画以向下和向上移动以放置文件夹内容。同时,我会添加一个表示文件夹内容的子视图,并在必要时以与其大小和位置相同的速度进行动画处理。
为了支持跨越整个屏幕的背景图像,我会将其切割成碎片并将这些碎片作为背景图像视图添加到每一行的视图中。
我写了一个快速而肮脏的示例代码,动画从任何点击位置开始,也可以在 github 上作为完整项目提供。
@interface ViewController ()
@property (nonatomic, strong) UIView *upperView;
@property (nonatomic, strong) UIView *lowerView;
@property (nonatomic, strong) UIImageView *upperImageView;
@property (nonatomic, strong) UIImageView *lowerImageView;
@property (nonatomic, strong) UIView *folderContentsView;
@property (nonatomic, assign) CGRect startRect;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
UIImage *bgImg = [UIImage imageNamed:@"bg.png"];
self.upperImageView = [[UIImageView alloc] initWithImage:bgImg];
self.lowerImageView = [[UIImageView alloc] initWithImage:bgImg];
[self.upperImageView setContentMode:UIViewContentModeTop];
[self.lowerImageView setContentMode:UIViewContentModeTop];
self.upperView = [[UIView alloc] initWithFrame:self.upperImageView.frame];
self.lowerView = [[UIView alloc] initWithFrame:self.lowerImageView.frame];
[self.upperView addSubview:_upperImageView];
[self.lowerView addSubview:_lowerImageView];
[self.view addSubview:_lowerView];
[self.view addSubview:_upperView];
UITapGestureRecognizer *upperTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(openOverlay:)];
UITapGestureRecognizer *lowerTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(openOverlay:)];
[self.upperView setUserInteractionEnabled:YES];
[self.upperView addGestureRecognizer:upperTapRecognizer];
[self.upperView setClipsToBounds:YES];
[self.lowerView setUserInteractionEnabled:YES];
[self.lowerView addGestureRecognizer:lowerTapRecognizer];
[self.lowerView setClipsToBounds:YES];
self.folderContentsView = [[UIView alloc] initWithFrame:CGRectZero];
self.folderContentsView.backgroundColor = [UIColor redColor];
UITapGestureRecognizer *closeTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(closeOverlay:)];
[self.folderContentsView addGestureRecognizer:closeTapRecognizer];
[self.view addSubview:self.folderContentsView];
[self.folderContentsView addSubview:[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"bgFolder.png"]]];
[self.folderContentsView setClipsToBounds:YES];
self.startRect = [self.upperView frame];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
-(void)openOverlay:(UITapGestureRecognizer *) sender
{
[self.upperView setUserInteractionEnabled:NO];
[self.lowerView setUserInteractionEnabled:NO];
CGPoint location = [sender locationInView:sender.view];
self.folderContentsView.frame = CGRectMake(0, location.y,
_lowerView.frame.size.width, 0);
self.lowerView.frame = CGRectMake(0, location.y,
_lowerView.frame.size.width, _lowerView.frame.size.height);
self.upperView.frame = CGRectMake(0, 0,
_upperView.frame.size.width, location.y);
self.lowerImageView.frame = CGRectMake(_lowerImageView.frame.origin.x, -location.y,
_lowerImageView.frame.size.width, _lowerImageView.frame.size.height);
[UIView animateWithDuration:.5 animations:^{
self.folderContentsView.frame = CGRectMake(0, location.y,
_lowerView.frame.size.width, 200);
self.lowerView.frame = CGRectOffset(_lowerView.frame, 0, 200);
}];
}
-(void) closeOverlay:(UITapGestureRecognizer*) sender
{
[UIView animateWithDuration:.5 animations:^{
self.lowerView.frame = CGRectOffset(_lowerView.frame, 0, -200);
self.folderContentsView.frame = CGRectMake(0, self.folderContentsView.frame.origin.y,
self.folderContentsView.frame.size.width, 0);
} completion:^(BOOL finished) {
[self.upperView setUserInteractionEnabled:YES];
[self.lowerView setUserInteractionEnabled:YES];
self.upperView.frame = self.startRect;
}];
}
@end
两个视图在图层中配备了相同的背景。如果检测到点击,则调整两个视图的大小,以便上视图在点击的 y 坐标处结束,而下视图从那里开始。添加到 lowerView 的 UIImageView 向相反方向移动,以便图像保持在原位。
现在 lowerView 向下滑动,同时添加 contentView 并以相同的速度调整大小。
如您所见,不需要图像渲染或其他艰难的操作。只是 UIView 动画。