这几天在看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,只不过被隐藏了。这样就达到了拖动的效果。