2014-10-16 111 views
2

我想創建一個UITableViewController,其中tableview上的加載動畫應該使項目從側面滑入。細胞的高度比默認的細胞高出大約5-7倍。我想要一個動畫,如在Android上看到的Google+加載動畫。 (卡片動畫)。UITableView的自定義加載動畫

我想像的是子類化TableView類,重寫一個加載方法,當它們被引入顯示器時顯示新項目,然後使用彈簧動畫同時旋轉單元格,同時其x和y值逐漸變化改變。

我在this answer中試過這段代碼,但並沒有完全實現。對這個答案的闡述和解釋也會很有幫助。代碼:

- (void)animate 
{ 
[[self.tableView visibleCells] enumerateObjectsUsingBlock:^(UITableViewCell *cell, NSUInteger idx, BOOL *stop) { 
    [cell setFrame:CGRectMake(320, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height)]; 
    [UIView animateWithDuration:1 animations:^{ 
     [cell setFrame:CGRectMake(0, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height)]; 
    }]; 
}]; 
} 

任何幫助將不勝感激! 埃裏克

回答

3

下面是你描述什麼(我相信)的功能完整的例子。我打開了一個空的單視圖項目,刪除了故事板中的視圖控件,並簡單地創建了一個UITableViewController並將其類設置爲我在下面創建的UITableViewController子類的類。

沒什麼加入頭文件,所以我排除它

#import "weeeTables.h" 

@interface weeeTables() 


@property (nonatomic, strong) NSMutableSet *shownIndexes; 
@property (nonatomic, assign) CATransform3D initialTransform; 

@end 

的shownIndexes將包含在已顯示的視圖索引,所以我們不要重複動畫滾動備份。該initialTransform屬性是變換單元的初始狀態(在您想要談到在屏幕上之前)

@implementation weeeTables 

- (void)viewDidLoad { 
[super viewDidLoad]; 

CGFloat rotationAngleDegrees = -30; 
CGFloat rotationAngleRadians = rotationAngleDegrees * (M_PI/180); 
CGPoint offsetPositioning = CGPointMake(-20, -20.0); 

CATransform3D transform = CATransform3DIdentity; 
transform = CATransform3DRotate(transform, rotationAngleRadians, -50.0, 0.0, 1.0); 
transform = CATransform3DTranslate(transform, offsetPositioning.x, offsetPositioning.y, -50.0); 
_initialTransform = transform; 

_shownIndexes = [NSMutableSet set]; 
} 
在viewDidLoad中

,我們設置爲初始值變換,我打了值的位,並鼓勵你也做同樣的事情以獲得你要找的效果,但是細胞目前從左下角開始動畫。

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
return 1; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
return 20; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
return 385; 
} 




- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"weeCell" forIndexPath:indexPath]; 


return cell; 
} 

一切都在上面的塊是一個UITableViewController子類非常典型的,並沒有特別的相關性添加動畫,我只設置一些靜態的數字,以補充充足的細胞通過,唯一的獨特的價值在這裏滾動是細胞標識符,正如你所看到的,它有一個非常仔細思考的名字。

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

if (![self.shownIndexes containsObject:indexPath]) { 

    [self.shownIndexes addObject:indexPath]; 
    UIView *weeeeCell = [cell contentView]; 

    weeeeCell.layer.transform = self.initialTransform; 
    weeeeCell.layer.opacity = 0.8; 

    [UIView animateWithDuration:.65 delay:0.0 usingSpringWithDamping:.85 initialSpringVelocity:.8 options:0 animations:^{ 
     weeeeCell.layer.transform = CATransform3DIdentity; 
     weeeeCell.layer.opacity = 1; 
    } completion:^(BOOL finished) {}]; 
} 
} 
@end 

這裏是一個真正的把它結合在一起的人,首先我們檢查,看看是否我們將要顯示的細胞已經在shownIndexes的名單,如果不是我們添加它,然後創建此當前單元格內容視圖的局部變量。

然後將contentView上的變換設置爲我們的初始變換(即我們在ViewDidLoad中設置的變換)。在用戶看到它之前,這個單元格會移動到我們的起始位置,然後我們將該變換動畫化回到標識變換。我也有不透明的地方,只是爲了它。

希望它有幫助!

+0

目前在學校,今晚將嘗試它;) – Erik 2014-10-17 07:10:01

+0

作品像一個魅力:)有什麼辦法可以改變這種動畫?有沒有其他的選擇?我看到我們設置了CATransform3DIdentity,但是我可以將其更改爲會產生不同動畫的其他內容嗎? – Erik 2014-10-17 13:29:38

+0

當然,這只是我在這個例子中選擇的路線,因爲它具有靈活性。主要思想是一個兩步過程,將單元格(或者在這種情況下,單元格內的內容視圖)放置在要從中開始動畫的位置,然後將該單元格放置到位。這兩個步驟都將在willDisplayCell方法中完成。 @ james_womack的迴應,這也是一個非常有效的方式來動畫細胞的位置。他只是將整個單元框架移出屏幕,然後使用UIView動畫API將其設置到位。 – domitall 2014-10-17 14:04:29

1

我會嘗試使用tableView:willDisplayCell:forRowAtIndexPath:

您可以設置的UITableViewCell到初始屏幕外邊框,然後異步初始化該單元格動畫。

我測試過這一點,它的工作原理使用Xcode主/詳細信息模板

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { 
     let frame = CGRectMake(-cell.frame.size.width, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height) 
     cell.frame = frame 

     UIView.animateWithDuration(1, delay: 0.1, options: UIViewAnimationOptions.CurveEaseInOut, animations: {() -> Void in 
      let endFrame = CGRectMake(100, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height) 
      cell.frame = endFrame 
     }) { (foo:Bool) -> Void in 
      // 
     } 
    } 

你只需要添加特殊的外殼爲不同的表現情況。當您有時再次返回視圖時,或者在單元格從視圖中滾動並重新打開之後,將調用此方法。