2012-12-30 29 views
3

起初我认为它不会太难,但结果是比我想象的还多一点。我应该如何重新创建iOS主屏幕打开文件夹动画?

iOS Folder Open

目前基于解决此我的代码的:https://github.com/jwilling/JWFolders。然而,它并不是很干净,最大的问题是每次打开文件夹时都会截图(renderInContext:对CPU非常重要,因此fps非常低)。除此之外,这个实现看起来并不像Apple动画那样干净整洁。

苹果设法拉出一个不会滞后的像素完美动画。我也想这样做!什么是最好的方式去做这个/你将如何做到这一点 - 一个干净的编码,漂亮,流畅的动画?目前,我的动画在所有这些领域都缺乏,我很难理解我能做得更好(就像苹果一样)。

-

我不乞求代码,只需一个最好的方法/如何。但是如果你想继续编码,那么我就没有办法说不(不过肯定会是合适的)!

+0

你只是想知道苹果是怎么做的(假设他们这样做是在App Store的兼容方式)?你对vikingsegundo的回答的评论听起来像你有苹果没有的要求。苹果公司的文件夹开放只需要分割墙纸,但是你的评论使得它听起来像你想要有更多的视角穿过接缝并分成两部分。 –

+0

@robmayoff我的情况与苹果公司的做法略有不同 - 只是假装文件夹没有很好地对齐,而且它是我所拥有的。不过,我很想知道苹果是如何做到这一点的,如果这种做法在我的情况下无法正常工作,那么我就可以做得很好。按照sudo rm -rf的说法,拆分壁纸并不是苹果公司的做法。下面的答案并不正确 - 我只是在等着看有没有人有更好的答案。 –

+0

@robmayoff也拆分壁纸并不像它看上去那么直截了当。首先,旋转(在iPad上)意味着壁纸在旋转时位置不同。另外,根据单击哪个文件夹,每个视图将不得不分配给不同的“后备视图”以添加到取决于是否要分割或放下(基于点击的文件夹)。文件夹也在打开时旋转。结合所有这些问题,它实际上导致了一些非常混乱的东西 - 我不相信苹果是这么做的,可能有更好的方法。 –

回答

3

我会将跳板分成几个视图,其中每个视图都是一行图标。
如果点击文件夹图标,我会为所有后续视图制作动画,向下移动并向上放置文件夹内容。同时我会添加一个代表文件夹内容的子视图,并根据需要以相同的速度对其大小和位置进行动画处理。

要支持跨越整个屏幕的背景图像,我会将其剪切为小块,并将这些小块作为背景图像视图添加到每行视图。


我写了一个快速和肮脏的示例代码与动画有关的任何抽头位置,也可作为complete project on github开始。

screenshot

@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动画。

enter image description here

+1

这可能不会太离谱。您还可以将其想象为具有可展开行的表格视图。 – jrturton

+0

@jrturton,我实际上想过提出使用可扩展单元格的表格视图。但这将取决于更多关于真实用例的知识。 – vikingosegundo

+0

有没有办法我可以动态地将UIView分割成几部分?这是一个很好的解决方案,唯一的问题是我的文件夹将从任意位置下降,这意味着我不能预先将背景视图分开 –

相关问题