這幾天在看AQGridView開源庫中的示例DEMO:SpringBoard,一直不明白裏面爲什麼會有empty cell,看了幾遍代碼終於明白了。
先看下面的代碼:
case UIGestureRecognizerStateBegan:
{
NSLog(@"UIGestureRecognizerStateBegan");
NSUInteger index = [_gridView indexForItemAtPoint: [recognizer locationInView: _gridView]];
_emptyCellIndex = index; // we'll put an empty cell here now
// find the cell at the current point and copy it into our main view, applying some transforms
AQGridViewCell * sourceCell = [_gridView cellForItemAtIndex: index];
CGRect frame = [self.view convertRect: sourceCell.frame fromView: _gridView];
_draggingCell = [[SpringBoardIconCell alloc] initWithFrame: frame reuseIdentifier: @""];
_draggingCell.icon = [_icons objectAtIndex: index];
[self.view addSubview: _draggingCell];
// grab some info about the origin of this cell
_dragOriginCellOrigin = frame.origin;
_dragOriginIndex = index;
[UIView beginAnimations: @"" context: NULL];
[UIView setAnimationDuration: 0.2];
[UIView setAnimationCurve: UIViewAnimationCurveEaseOut];
// transformation-- larger, slightly transparent --> 按住後,原來的圖標變大和透明 by jfl
_draggingCell.transform = CGAffineTransformMakeScale( 1.2, 1.2 );
_draggingCell.alpha = 0.7;
// also make it center on the touch point
_draggingCell.center = [recognizer locationInView: self.view];
[UIView commitAnimations];
// reload the grid underneath to get the empty cell in place |--> 加載放大之後,下面的那個empty cell的,如果註釋掉這段代碼,變化之前的icon還在原地 by jfl
NSLog(@"**********");
// [_gridView reloadItemsAtIndices: [NSIndexSet indexSetWithIndex: index]
// withAnimation: AQGridViewItemAnimationNone];
NSLog(@"----------");
break;
}
如果我們把
// [_gridView reloadItemsAtIndices: [NSIndexSet indexSetWithIndex: index]
// withAnimation: AQGridViewItemAnimationNone];
註釋掉。運行程序會發現如下效果:
在我們拖動的過程當中,左邊原來的圖標會一直顯示,這顯然是不對的。
如果不註釋掉那個代碼它就會調用下面的方法:
- (AQGridViewCell *) gridView: (AQGridView *) gridView cellForItemAtIndex: (NSUInteger) index
{
NSLog(@"gridView cellForItemAtIndex");
static NSString * EmptyIdentifier = @"EmptyIdentifier";
static NSString * CellIdentifier = @"CellIdentifier";
if ( index == _emptyCellIndex )
{
NSLog( @"Loading empty cell at index %u", index );
AQGridViewCell * hiddenCell = [gridView dequeueReusableCellWithIdentifier: EmptyIdentifier];
if ( hiddenCell == nil )
{
// must be the SAME SIZE AS THE OTHERS
// Yes, this is probably a bug. Sigh. Look at -[AQGridView fixCellsFromAnimation] to fix
hiddenCell = [[AQGridViewCell alloc] initWithFrame: CGRectMake(0.0, 0.0, 72.0, 72.0)
reuseIdentifier: EmptyIdentifier];
}
// 如果把這行代碼註釋掉,icon下面會出現個白色的矩形,所以才用EmptyIdentifier | by jfl
// hiddenCell.hidden = YES;
return ( hiddenCell );
}
SpringBoardIconCell * cell = (SpringBoardIconCell *)[gridView dequeueReusableCellWithIdentifier: CellIdentifier];
if ( cell == nil )
{
cell = [[SpringBoardIconCell alloc] initWithFrame: CGRectMake(0.0, 0.0, 72.0, 72.0) reuseIdentifier: CellIdentifier];
}
cell.icon = [_icons objectAtIndex: index];
return ( cell );
}
此時,index == _emptyCellIndex,它會返回那個hiddenCell,即empty cell。然後把它隱藏,這樣,我們在拖動的過程當中就看不到它了,達到了要實現的效果。
如果我們把
// hiddenCell.hidden = YES;
註釋掉,可以看到下面的效果:
這其實就是拖動過程當中一直有這個empty cell,只不過被隱藏了。這樣就達到了拖動的效果。