UICollectionViews で非常に奇妙な動作が見られます。
これがシナリオです。
UINavigationController スタックにプッシュされた UIViewController があります。
UIViewController ビューには、グリッド レイアウトのナビゲーション バーと UICollectionView があります。幅 3 セル、高さ無制限。
画面の範囲のすぐ下に、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 の delete メソッドでアニメーションを実行しておらず、編集モードを終了する Done ボタンを押したときだけです。このメソッドが呼び出されていないことを確認しました。
また、UIToolbar が実際に動いていないことも確認しました。UIToolbar が通常は消える場合に削除を押すときに「self.collectionview removeFromSuperView」を追加すると、UIToolbar は画面上の期待どおりの場所になります。これは、親ビューの描画で UICollectionView が何らかの形でレイヤー階層を変更しているという印象を与えます。
UIToolbar の BringSubviewToFront と collectionview の sendSubviewToBack を試みましたが、影響はありません。
開いているツールバーを再度開始すると、uitoolbar が再びアニメーション化されます。ただし、奇妙なことに、画面の下からアニメーション化されるようです! これは、removeFromSuperview 呼び出しを呼び出した後で UICollectionView が何らかの理由で UIToolbar を画面から押し出して再作成できない場合を除き、意味がありません。
私が持っている1つの「解決策」は、UIToolbarを強制的に元の位置に戻すことですが、0.01秒の遅延後にアニメーションはありません
[self performSelector:@selector(showToolbarNoAnimation) withObject:nil afterDelay:0.01];
これは機能します。
ここに質問があります: UICollectionView がこの動作を引き起こし、行全体が削除された後に UIToolbar を画面外に押し出す理由は何ですか? ハックは機能しますが、問題を説明していません。
ありがとう、ジェームズ