animation类似于在ios7中打开应用程序

我想创build一个类似于在iOS7中iPhone中打开的应用程序的animation。 在这个animation中,它只是显示应用程序正在从哪个点打开,并在同一点closures。

谁能帮帮我吗?

@property (weak, nonatomic) IBOutlet UIImageView *bg; @property (weak, nonatomic) IBOutlet UIImageView *cal; … bool nowZoomed = NO; CGRect iconPosition = {16,113,60,60}; // customize icon position - (CGRect)zoomedRect // just a helper function, to get the new background screen size { float screenWidth = UIScreen.mainScreen.bounds.size.width; float screenHeight = UIScreen.mainScreen.bounds.size.height; float size = screenWidth / iconPosition.size.width; float x = screenWidth/2 - (CGRectGetMidX(iconPosition) * size); float y = screenHeight/2 - (CGRectGetMidY(iconPosition) * size); return CGRectMake(x, y, screenWidth * size, screenHeight * size); } - (IBAction)test { float animationDuration = 0.3f; //default if (nowZoomed) // zoom OUT { [UIView animateWithDuration:animationDuration animations:^{ // animate to original frame _cal.frame = iconPosition; _bg.frame = UIScreen.mainScreen.bounds; } completion:^(BOOL finished) { [UIView animateWithDuration:animationDuration/2.0f animations:^{ // then fade out _cal.alpha = 0.0f; } completion:^(BOOL finished) { _cal.hidden = YES; }]; }]; } else // zoom IN { _cal.alpha = 0.0f; _cal.hidden = NO; [UIView animateWithDuration:animationDuration/2.0f animations:^{ // fade in faster _cal.alpha = 1.0f; }]; [UIView animateWithDuration:animationDuration animations:^{ // while expanding view _cal.frame = UIScreen.mainScreen.bounds; _bg.frame = [self zoomedRect]; }]; } nowZoomed = !nowZoomed; } 

你可以通过创build一个这样的示例项目来testing它:

  • 从模拟器(如主屏幕和日历视图)做两个截图或抓住这两个: 主屏幕 / 日历
  • 将2个图像视图和1个button添加到故事板
  • 使背景图像视图与整个屏幕一样大
  • 和其他图像视图与这个尺寸: {16,113,60,60}
  • 创build一个IBOutlet (前两行代码)
  • 设置button动作目标为-(void)test

故事板动画 故事板图片(左)和animation过渡(右)

我个人更喜欢在这种情况下使用CGAffineTransformMakeScale()和设置-[CALayer affineTransform]

affineTransform非常易于使用,并且具有Core Animation的一些不错的,隐含的好处。 例子就是像处理改变框架的起源给你隐含的,使得它很容易重新恢复到初始大小,如果需要的话 – 你从来没有把它放在第一位!

 [UIView animateWithDuration:0.3 animations:^{ view.layer.affineTransform = CGAffineTransformMakeScale(10.0, 10.0); // To make a view larger: otherView.layer.affineTransform = CGAffineTransformMakeScale(0.0, 0.0); // to make a view smaller }]; 

 // To reset views back to their initial size after changing their sizes: [UIView animateWithDuration:0.3 animations:^{ view.layer.affineTransform = CGAffineTransformIdentity; otherView.layer.affineTransform = CGAffineTransformIdentity; }]; 

据我所知,该animation是使用截图。 它更新视图的框架,同时从应用程序徽标平滑过渡到应用程序的屏幕截图。 我模仿iPod(音乐)应用程序从设备的右下angular开始到屏幕尺寸:

 UIView * v = [[UIView alloc]init]; CGSize size = self.view.bounds.size; CGRect frameInitial = CGRectMake(size.width - 30, size.height - 30, 20, 20); CGRect frameFinal = CGRectMake(0,0, size.width, size.height); [v setFrame:frameInitial]; 

然后使用下面的行来当你想animation的框架大小:

 [UIView animateWithDuration:0.3f delay:0.0f options:UIViewAnimationOptionBeginFromCurrentState animations:^{ [v setFrame:frameFinal]; } completion:nil]; 

编辑:没有意识到,缩放还包括背景。 下面的代码没有testing(我不在工作),所以期待一些缺陷和错别字。

想象一下你在视图控制器的视图上有两层。 直接在vc上有你想要打开的应用程序,可以称之为finalView。 在顶层有一个窗口与所有的应用程序,这将放大和淡入到你的应用程序,这是一个看法。 让我们叫它firstView。

初始条件:firstView有一个320 x 480的框架(这是一个包含所有应用程序图标的窗口)。 它具有1的alpha。finalView具有相同的框架和alpha,但是它位于firstView之后。 Final cond:finalView仍然有相同的框架和alpha。 但firstView将放大到右下angular(将有一个巨大的框架)和淡出(alpha – > 0)。

//初始条件:(或更好的使用IB)

 CGRect frameInitial = CGRectMake(0,0, self.view.size.width, self.view.size; CGRect frameFinal = CGRectMake(self.view.size.width * -4 ,self.view.size.height * -5, self.view.size.width * -5,self.view.size.width * -6); [v setFrame:frameInitial]; 

然后使用下面的行来当你想animation的框架大小:

 [UIView animateWithDuration:0.3f delay:0.0f options:UIViewAnimationOptionBeginFromCurrentState animations:^{ [v setFrame:frameFinal]; } completion:nil]; 

我有一个小回购,使用UICollectionViewFloatLayout创build缩放效果, https://github.com/MichaelQuan/ios7ZoomEffect 。 这仍然是一个正在进行的工作,但基本的想法在那里

布局代码是:

 @interface ExpandingCollectionViewLayout () @property (nonatomic, assign) CGRect selectedCellFrame; @property (nonatomic, strong) NSIndexPath *selectedIndexPath; @end - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { NSArray *layoutAttributes = [super layoutAttributesForElementsInRect:rect]; [layoutAttributes enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes *obj, NSUInteger idx, BOOL *stop) { [self _transformLayoutAttributes:obj]; }]; return layoutAttributes; } - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewLayoutAttributes *layoutAttributes = [super layoutAttributesForItemAtIndexPath:indexPath]; [self _transformLayoutAttributes:layoutAttributes]; return layoutAttributes; } - (void)_transformLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes { if (self.selectedIndexPath != nil) { if ([layoutAttributes.indexPath isEqual:self.selectedIndexPath]) { // set the frame to be the bounds of the collectionView to expand to the entire collectionView layoutAttributes.frame = self.collectionView.bounds; } else { //scale = collectionView.size / cell_selected.size //translate = (scale - 1)(cell_i.center - cell_selected.center) + (collectionView.center - cell_selected.center) CGRect collectionViewBounds = self.collectionView.bounds; CGRect selectedFrame = self.selectedCellFrame; CGRect notSelectedFrame = layoutAttributes.frame; // Calculate the scale transform based on the ratio between the selected cell's frame and the collection views bound // Scale on that because we want everything to look scaled by the same amount, and the scale is dependent on how much the selected cell has to expand CGFloat x_scale = collectionViewBounds.size.width / selectedFrame.size.width; CGFloat y_scale = collectionViewBounds.size.height / selectedFrame.size.height; CGAffineTransform scaleTransform = CGAffineTransformMakeScale(x_scale, y_scale); // Translation based on how much the selected cell has been scaled // translate based on the (scale - 1) and delta between the centers CGFloat x_zoomTranslate = (x_scale - 1) * (CGRectGetMidX(notSelectedFrame) - CGRectGetMidX(selectedFrame)); CGFloat y_zoomTranslate = (y_scale - 1) * (CGRectGetMidY(notSelectedFrame) - CGRectGetMidY(selectedFrame)); CGAffineTransform zoomTranslate = CGAffineTransformMakeTranslation(x_zoomTranslate, y_zoomTranslate); //Translation based on how much the cells are scaled // Translation based on where the selected cells center is // since we move the center of the selected cell when expanded to full screen, all other cells must move by that amount as well CGFloat x_offsetTranslate = CGRectGetMidX(collectionViewBounds) - CGRectGetMidX(selectedFrame); CGFloat y_offsetTranslate = CGRectGetMidY(collectionViewBounds) - CGRectGetMidY(selectedFrame); CGAffineTransform offsetTranslate = CGAffineTransformMakeTranslation(x_offsetTranslate, y_offsetTranslate); // multiply translations first CGAffineTransform transform = CGAffineTransformConcat(zoomTranslate, offsetTranslate); transform = CGAffineTransformConcat(scaleTransform, transform); layoutAttributes.transform = transform; } } } 

要使用此布局代码展开单元格,请将selectedCellFrameselectedIndexPath设置为要展开的单元格,并在集合视图上调用performBatchUpdates:completion: 要折叠set selectedCellFrame = CGRectNullselectedIndexPath = nil并调用performBatchUpdates:completion: