【发布时间】:2013-08-16 21:13:38
【问题描述】:
我发现 UICollectionViews 的行为非常奇怪。
这是场景。
我有一个 UIViewController 已被推送到 UINavigationController 堆栈。
UIViewController 视图在网格布局中有导航栏和 UICollectionView。 3 格宽 x 无限高。
就在屏幕范围的下方,我还隐藏了一个 UIToolbar。 UIToolbar 在层级中位于 UICollectionView 之上。
然后我允许用户将视图置于“编辑模式”,并将 UIToolbar 动画到屏幕上并覆盖 UICollectionView 的底部。如果用户离开“编辑模式”,我会将 UIToolbar 移出屏幕。
在“编辑模式”下,我允许用户多选带有复选框的单元格,并且 uitoolbar 具有删除按钮。
删除执行以下操作:
- (void)deletePhotos:(id)sender {
if ([[self.selectedCells allKeys] count] > 0) {
[[DataManager instance] deletePhotosAtIndexes:[self.selectedCells allKeys]];
[self.selectedCells removeAllObjects];
[self.collectionview reloadData];
[self.collectionview performBatchUpdates:nil completion:nil];
}
}
// Data Manager method in singleton class:
- (void)deletePhotosAtIndexes:(NSArray *)indexes {
NSMutableIndexSet *indexesToDelete = [NSMutableIndexSet indexSet];
for (int i = 0; i < [indexes count]; i++) {
[indexesToDelete addIndex:[[indexes objectAtIndex:i] integerValue]];
NSString *filePath = [self.photosPath stringByAppendingPathComponent:[self.currentPhotos objectAtIndex:[[indexes objectAtIndex:i] integerValue]]];
NSString *thumbnailPath = [self.thumbPath stringByAppendingPathComponent:[self.currentPhotos objectAtIndex:[[indexes objectAtIndex:i] integerValue]]];
if ([[NSFileManager defaultManager] fileExistsAtPath: filePath]) {
[[NSFileManager defaultManager] removeItemAtPath: filePath error:NULL];
[[NSFileManager defaultManager] removeItemAtPath: thumbnailPath error:NULL];
}
}
[self.currentPhotos removeObjectsAtIndexes:indexesToDelete];
}
数据管理器包含照片对象,并像这样用于单元格创建。
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
ImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"imageCell" forIndexPath:indexPath];
NSString *pngfile = [[[DataManager instance] thumbPath] stringByAppendingPathComponent:[[[DataManager instance] currentPhotos] objectAtIndex:indexPath.row]];
if ([[NSFileManager defaultManager] fileExistsAtPath:pngfile]) {
NSData *imageData = [NSData dataWithContentsOfFile:pngfile];
UIImage *img = [UIImage imageWithData:imageData];
[cell.imageView setImage:img];
}
if ([self.selectedCells objectForKey:[NSString stringWithFormat:@"%d", indexPath.row]] != nil) {
cell.checkbox.hidden = NO;
} else {
cell.checkbox.hidden = YES;
}
return cell;
}
所以这里是我发现问题的地方:
当删除足够多的单元格以使可见行数发生变化时,UIToolbar 正在消失。在整行 3 的情况下,如果我只删除 1 或 2 个项目,UIToolbar 不会消失。我没有在删除方法中的 UIToolbar 上做任何动画,只有在点击结束编辑模式的完成按钮时。我已确认没有调用此方法。
我还确认 UIToolbar 实际上并没有移动。如果我在 UIToolbar 通常会消失的情况下在点击删除时添加“self.collectionview removeFromSuperView”,那么 UIToolbar 正是屏幕上预期的位置。这给我的印象是 UICollectionView 在绘制父视图时以某种方式改变了图层层次结构。
我已尝试为 UIToolbar 带来 SubviewToFront,为 collectionview 尝试 sendSubviewToBack,但没有任何影响。
重新启动打开的工具栏会导致 uitoolbar 重新设置动画。但奇怪的是,它似乎从屏幕下方开始设置动画!这是没有意义的,除非 UICollectionView 在我调用 removeFromSuperview 调用之后以某种方式将 UIToolbar 推离屏幕,因此我无法重新创建。
我的一个“解决方案”是强制 UIToolbar 在 0.01 秒延迟后返回原位但没有动画
[self performSelector:@selector(showToolbarNoAnimation) withObject:nil afterDelay:0.01];
这行得通。
这是一个问题: 知道为什么 UICollectionView 在删除整行后导致此行为将 UIToolbar 推到屏幕外吗? hack 有效,但没有解释问题。
谢谢, 詹姆斯
【问题讨论】:
-
你在使用自动布局吗?
-
是的。 UIToolbar 在屏幕外与 UICollectionView 的底部边缘对齐。
标签: uicollectionview autolayout