2013-08-16 43 views
0

我看到一個非常奇怪的行爲與UICollectionViews。UICollectionView視圖圖層優先級

這是場景。

我有一個UIViewController已推到UINavigationController堆棧。

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正在消失。如果我只刪除1或2個項目,UIToolbar不會消失。我沒有在刪除方法中的UIToolbar上做任何動畫,只有當點擊一個完成按鈕,結束編輯模式。我已確認此方法未被調用。

我也確認UIToolbar並未實際移動。如果在UIToolbar正常消失的情況下在添加「self.collectionview removeFromSuperView」時添加了「self.collectionview removeFromSuperView」,則UIToolbar正好在屏幕上的預期位置。這給我的印象是UICollectionView以某種方式改變了父視圖繪製中的圖層層次結構。

我試圖嘗試爲UIToolbar和sendSubviewToBack爲collectionview帶來SubviewToFront並沒有任何影響。

重新打開打開的工具欄會導致uitoolbar重新生成動畫。奇怪的是,它似乎是從屏幕下方生成的!這是沒有意義的,除非UICollectionView以某種方式將UIToolbar從屏幕上推出,因爲在我將調用removeFromSuperview調用之後,我無法重新創建。

一個「解決方案」我已經很給力了UIToolbar回來到位置,但沒有動畫0.01秒的延遲

[self performSelector:@selector(showToolbarNoAnimation) withObject:nil afterDelay:0.01]; 

這工作後。

這裏是一個問題: 任何想法爲什麼UICollectionView導致這種行爲推UIToolbar屏幕後刪除整行?黑客的作品,但沒有解釋這個問題。

謝謝, 詹姆斯

+0

您是否使用自動佈局? –

+0

是的。 UIToolbar在屏幕之外對齊到UICollectionView的底部邊緣。 –

回答

1

當您使用自動佈局,你的觀點是從故事板加載(或廈門國際銀行),則不能設置你的意見的框架。這樣做看起來可能最初起作用,但是在某些時候,自動佈局會根據約束來重置視圖的框架,並且您不會理解發生了什麼,然後您會向堆棧溢出發佈問題。

如果您需要更改視圖的佈局,則需要改爲更新視圖的約束。

存在一個約束,指定工具欄底部邊緣與其超級視圖底部邊緣之間的距離。推測該距離是-44(其中44是工具欄的高度)。

您需要將該約束連接到視圖控制器中的插座。該插座將具有類型NSLayoutConstraint *。稱它爲toolbarBottomEdgeConstraint

當你想要的工具欄在屏幕上,動畫設置約束的constant爲零,在動畫塊中調用layoutIfNeeded

- (void)showToolbarAnimated { 
    [UIView animateWithDuration:0.25 animations:^{ 
     self.toolbarBottomEdgeConstraint.constant = 0; 
     [self.toolbar layoutIfNeeded]; 
    }]; 
} 

要隱藏工具欄,設置約束的constant回到其原始值:

- (void)hideToolbarAnimated { 
    [UIView animateWithDuration:0.25 animations:^{ 
     self.toolbarBottomEdgeConstraint.constant = -toolbar.bounds.size.height; 
     [self.toolbar layoutIfNeeded]; 
    }]; 
}