iOS 6 CollectionView 动态改变布局

Posted

技术标签:

【中文标题】iOS 6 CollectionView 动态改变布局【英文标题】:iOS 6 CollectionView Dynamically change Layout 【发布时间】:2013-02-16 19:26:38 【问题描述】:

我是UICollectionView 的新手,我正在从事一个在给定操作中动态更改UICollectionViewLayout 的项目。

我的 CollectionView 有 6 个部分,每个部分包含 10 个元素。这些单元格基本上是一个UIImageView,我的自定义布局称为StackViewLayout 堆叠每个部分的所有元素(类似于Apple 的Photos.app)。

如果用户选择堆栈的元素(对于所有部分),UICollectionView 会动态地将布局更改为UICollectionViewFlowLayout,因此所有元素都可以视为网格。

我的问题是,当用户选择一个堆栈时,无论哪个部分,当布局更改为流布局时,所有部分都显示在网格中,而不是显示所选部分(堆栈)的元素,即我想要的行为。

有没有办法在自定义布局中只显示选定部分的流布局?

这是我的控制器实现 sn-p 代码:

- (void)viewDidLoad

    [super viewDidLoad];
    [self loadStackLayout]; // stack all sections at first load.


#pragma mark - UICollectionView Data Source Methods

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView

    return 6;


- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section

    return 10;


- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;

    // custom UICollectionViewCell, which will hold an image.
    CVCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MyCell" forIndexPath:indexPath];        
    cell.imageView.image = _images[indexPath.row];
    return cell;


- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath

    // element size.
    return CGSizeMake(100,100);


-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath

    if (isStacked)
    
         [self loadFlowLayout]; //HERE I WANT TO LOAD FLOW LAYOUT ONLY FOR THE SECTION OF THE SELECTED ITEM!
     else
       
           // to implement.
       


// HERE IS THE METHOD THAT CALLS MY CUSTOM LAYOUT IN ORDER TO STACK THE ELEMENTS FOR EACH SECTION IN COLLECTION VIEW. IT IS WORKING AS IT SHOULD.
-(void)loadStackLayout

    if (([self.collectionView.collectionViewLayout isKindOfClass:[UICollectionViewFlowLayout class]]))
    
        isStacked = YES;
        [self.collectionView setCollectionViewLayout:[[StackViewLayout alloc] init] animated:YES];
    


// HERE IS THE METHOD THAT CALLS MY FLOWLAYOUT IN ORDER TO UN-STACK THE ELEMENTS AND SHOW THEM IN A GRID. CURRENTLY IT IS SHOWING ALL SECTIONS IN THE GRID.
-(void)loadFlowLayout

    if (([self.collectionView.collectionViewLayout isKindOfClass:[StackViewLayout class]]))
    
        isStacked = NO;
        [self.collectionView setCollectionViewLayout:[[UICollectionViewFlowLayout alloc] init] animated:YES];
    

【问题讨论】:

【参考方案1】:

我认为您可能可以通过在 numberOfItemsInSection: 方法中使用 if 子句来为任何不是选定部分的部分返回 0。显然,您需要跟踪所选部分才能执行此操作。

【讨论】:

好吧,我尝试为所有部分返回 0,但在 numberOfItensInSection 中选择了一个,但事实证明 xcode 给了我非常糟糕的访问权限(没有任何进一步的细节)。 if 子句仅在我为未选择的部分设置 return 1 项并在堆栈中选择第 0 部分(点击它)时才有效。任何其他组合都会导致应用崩溃。

以上是关于iOS 6 CollectionView 动态改变布局的主要内容,如果未能解决你的问题,请参考以下文章

动态大小的 collectionView 单元格导致可见性问题 - iOS

iOS collectionView.sizeForItemAtIndexPath 在 iPhone 6 之前的任何东西上都会中断

ios 两个 TableView 之间的联动, TableView 与 CollectionView 之间的联动

iOS 方向 UICollectionView

如何设置动态宽度 UICollectionViewCell

iOS UICollectionView左右滚动和上下滑动处理