標籤:
最近使用豌豆莢一覽的app時看到它的點擊cell後彈出介面的動畫很帥,所以自己琢磨著實現了一個,效果如下:
仔細觀察的話效果分為幾個部分,點擊cell的時候,首先背景會出現陰影,只有點擊的cell還亮著,然後有一點點的放大效果,同時cell的介面在慢慢變成純白色,最後上下炸開進入內容介面,其實仔細想想,這個和3D Touch的peek效果的前奏不是很像嘛。
弄清楚動畫的組成成分以後,開始動手實現,怎麼實現列表和詳情介面就不說了,可以在文末我的樣本工程裡面看,直接說cell的點擊後執行的過程。
我們這裡需要額外用到三個小vied,一個是背景的陰影view,一個是點擊的cell的view,一個是cell慢慢變成的純白色view(最後炸開的也是這個純白的view)。
所以我們先聲明者三個view:
@property (nonatomic, strong) UIView *tempView;// 純白view@property (nonatomic, strong) UIView *bgView;// 陰影視圖@property (nonatomic, strong) BookListCellView *selectedCell;// 選中的cell
這個聲明要做成整個視圖控制器可調用的,為什麼呢?因為這三個視圖是在我們點擊的時候添加的,我們必須進行移除,否則從詳情介面回來列表介面之後,這三個視圖還會存在,所以我們要在viewWillAppear方法中將其移除:
- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.tempView removeFromSuperview]; [self.bgView removeFromSuperview]; [self.selectedCell removeFromSuperview];}
三個視圖中,背景的陰影視圖是固定大小的,即使覆蓋整個介面,cell視圖和純白視圖要根據點擊的位置決定,所以陰影視圖可以直接寫一個方法來建立:
// 陰影視圖- (UIView *)bgView { if (nil == _bgView) { _bgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREENWIDTH, SCREENHEIGHT)]; _bgView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5]; } return _bgView;}
接下來就是動畫的部分了,我們去到點擊cell的方法,也就是
- (void)tableView:(UITableView )tableView didSelectRowAtIndexPath:(NSIndexPath )indexPath
方法,代碼如下:
#pragma mark TableView Delegate// 選中某一行- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:YES];// 選中後取消選中的顏色 // 詳情視圖 DetailViewController *detailVC = [[DetailViewController alloc] init]; // 擷取選中的地區範圍 CGRect rectInTableView = [self.tableView rectForRowAtIndexPath:indexPath]; CGRect sourceRect = [self.tableView convertRect:rectInTableView toView:[self.tableView superview]]; // 執行個體化選中的cell視圖,內容根據選中的cell內容來擷取,範圍使用上面擷取的範圍 self.selectedCell = (BookListCellView *)[self tableView:tableView cellForRowAtIndexPath:indexPath]; self.selectedCell.frame = sourceRect; self.selectedCell.backgroundColor = [UIColor whiteColor]; [self.view addSubview:self.selectedCell]; // 陰影視圖 [self bgView]; [self.view addSubview:_bgView]; // 將cell視圖放在最前面 [self.view bringSubviewToFront:self.selectedCell]; // 執行個體化純白視圖,範圍和cell視圖一樣,先做成透明 self.tempView = [[UIView alloc] initWithFrame:self.selectedCell.frame]; self.tempView.backgroundColor = [UIColor whiteColor]; self.tempView.alpha = 0; [self.view addSubview:self.tempView]; // 進行動畫 [UIView animateWithDuration:0.3 animations:^{ // 稍微增加cell視圖的大小 self.selectedCell.transform = CGAffineTransformMakeScale(1.0, 1.1); // 純白視圖的透明度設為不透明,這樣就會覆蓋cell視圖 self.tempView.alpha = 1; }]; // 順延強制 double delayInSeconds = 0.3; __block ViewController* bself = self; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ [bself.selectedCell removeFromSuperview]; // 進行動畫 [UIView animateWithDuration:0.3 animations:^{ // 炸開純白視圖到全屏 bself.tempView.transform = CGAffineTransformMakeScale(1.0, SCREENHEIGHT / bself.tempView.frame.size.height * 2); }]; }); // 順延強制 double delayInSeconds2 = 0.6; dispatch_time_t popTime2 = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds2 * NSEC_PER_SEC)); dispatch_after(popTime2, dispatch_get_main_queue(), ^(void){ // 進入詳情介面 [bself.navigationController pushViewController:detailVC animated:NO]; });}
注釋解釋了大部分的內容,我們來拆分一下,整個動畫分為三個過程:
- 第一個過程是加陰影,新建立一個對應的cell顯示出來,在動畫中稍微增大cell凸顯效果,同時有一個純白視圖慢慢覆蓋cell視圖;
- 第二個過程是炸開純白視圖,在動畫中將其的大小設為整個螢幕大小,就可以實現炸開覆蓋效果;
- 第三個過程就是進入詳情介面。
第二個過程和第三個過程都要分別加上延時才能正確執行,否則會一起執行就看不出效果了。動畫是使用的最基本的UIView動畫,教程可以看我這篇部落格,使用起來還是很方便的,順延強制我用的GCD的方法,也可以用別的你熟悉的方式。可以看出我們把三個新的視圖覆蓋在了介面上,所以每次列表介面要出現的時候我們就要將其移除,如上所述。要注意的是我們不能直接使用點擊到的cell的位置,經測試直接用他的原點會變成(0, 0),也就是出現在左上方,我也不知道為什麼,所以這裡要先擷取對應的地區來更改cell的範圍並作為純白view的範圍。
這樣就實現啦,效果很不錯的,可以下載我的樣本工程玩一玩~
著作權:http://blog.csdn.net/cloudox_
iOS點擊TableView的cell顯示彈齣動畫