简体   繁体   English

具有两个单元格的UICollectionView自定义布局

[英]UICollectionView custom layout with two cells

I've been reading online tutorials on UICollectionView with different layouts. 我一直在阅读关于UICollectionView具有不同布局的在线教程。 Also looked at a lot of SO Questions on the subject. 还看了很多关于该主题的SO问题。 But it seems what I am looking might be something more simple but I am stuck on how to go forward. 但是看来我正在寻找的东西可能更简单,但我仍然坚持前进。

The Goal 目标

I have a UIViewController that is embedded in a UINavigation controller. 我有一个嵌入在UINavigation控制器中的UIViewController I am displaying data in a UITableView which includes:1 UIImageView and three UILabels in each cell. 我正在UITableView中显示数据,其中包括:1个UIImageView和每个单元格中的三个UILabel。 The data is fetched from a server and all works nicely. 数据是从服务器获取的,并且一切正常。

I then wanted to have a UIButton that, when tapped, would kick off a cool animation that shows the cells transition into a nice grid view. 然后,我想有一个UIButton,当点击它时,它将启动一个很酷的动画,该动画显示单元格过渡到一个漂亮的网格视图。

It suddenly dawned on me that I needed to use a UICollectionView to change between these two cells and ditch the UITableView completely. 我突然意识到我需要使用UICollectionView在这两个单元格之间进行切换,并完全UICollectionView UITableView。 Tapping the button again, would switch back to the last state (Grid or UITableView style) 再次轻按该按钮,将切换回上一个状态(网格或UITableView样式)

The grid cell needs to loose one label - but keep the image. 网格单元需要松开一个标签-但要保留图像。

The problem 问题

I have spent the last two days reading up on UICollectionView and UICollectionViewFlowLayout . 最近两天,我一直在阅读UICollectionViewUICollectionViewFlowLayout I think I could use a Apple's pre-made UICollectionViewFlowLayout and just tweak it a little. 我想我可以使用苹果公司的预制UICollectionViewFlowLayoutUICollectionViewFlowLayout调整。

I don't know if I need two custom cells or one cell that changes shape between the two views and how the animations must work. 我不知道是否需要两个自定义单元格或一个需要在两个视图之间改变形状以及动画如何工作的单元格。

I'm not looking for the exact code to do this - I just need to know which direction I need to go in and if I need to use two custom cells - and how do I change between the two with animation and not reloading all the data again. 我不是在寻找执行此操作的确切代码-我只需要知道我需要进入哪个方向以及是否需要使用两个自定义单元格-以及如何在两个动画之间切换而不重新加载所有数据。

Appreciate any input. 感谢任何输入。

Thanks all. 谢谢大家

I finally found a solution that was acceptable to my need. 我终于找到了可以接受的解决方案。 If anyone ever has similar needs - this is how you use two different custom UICollectionViewCell 's and how to change between the two different cells / layouts. 如果有人有类似的需求-这就是您使用两个不同的自定义UICollectionViewCell的方式,以及如何在两个不同的单元格/布局之间进行更改。

  • First thing is create the customCells in IB - creating the xib files. 第一件事是在IB中创建xib创建xib文件。
  • Then set the up as you need 然后根据需要进行设置

Since my requirement needed the standard flow layout provided by the class UICollectionViewFlowLayout - I just needed to create two custom layouts and tweak them to my needs. 由于我的需求需要UICollectionViewFlowLayout类提供的标准流程布局-我只需要创建两个自定义布局并将其调整为我的需要即可。

  • Create two (or more if needed) classes that subclass UICollectionViewFlowLayout 创建两个(或多个,如果需要)子类,这些子类UICollectionViewFlowLayout

In the implementation - setup the layout as needed. 在实施中-根据需要设置布局。 Since I am subclassing the pre-made UICollectionViewFlowLayOut and all I need to do is tweak it - the implementation is pretty simple. 由于我继承了预制的UICollectionViewFlowLayOut的子类,因此我需要做的就是对其进行调整-实现非常简单。

So - for the table view layout I did this: 所以-对于表格视图布局,我这样做:

tableViewFlowLayOut.m

-(id)init
{
    self = [super init];

    if (self){

        self.itemSize = CGSizeMake(320, 80);
        self.minimumLineSpacing = 0.1f;
    }

    return self;
}

This sets each cells width and height to the values I needed. 这将每个单元格的宽度和高度设置为我需要的值。 self.minimumLineSpacing sets the spacing between the cells. self.minimumLineSpacing设置单元格之间的间距。 (Spacing between the cell above / below ) (上方/下方的单元格之间的间距)

Then for the grid layout: 然后对于网格布局:

gridFlowLayOut.m

-(id)init
{
    self = [super init];

    if (self){

        self.itemSize = CGSizeMake(159, 200);
        self.minimumInteritemSpacing = 0.1f;
        self.minimumLineSpacing = 0.1f;
    }
    return self; 
}

Same as before - however, this time I needed spacing between my cells right edge - 与以前一样-但是,这次我需要在单元格右边缘之间保持间距-

self.minimumInteritemSpacing = 0.1f'

takes care of that. 照顾那个。

Right - now to put it all together - in the viewController that has the UICollectionView 现在-现在将它们放在一起-在具有UICollectionView的UICollectionView

viewController.m

// Import the new layouts needed. 

#import "GridFlowLayOut.h"
#import "TableViewFlowLayOut.m"

//Create the properties 

@property (strong, nonatomic) TableViewFlowLayOut *tableViewLayout;
@property (strong, nonatomic) GridFlowLayOut *grideLayout;

-(void)viewDidLow
{
//Register the two custom collection view cells you created earlier. Make sure you set the correct reuse identifier here. 

[self.tradeFeedCollectionView registerNib:[UINib nibWithNibName:@"TableViewCell" bundle:nil] forCellWithReuseIdentifier:@"TableItemCell"];
    [self.tradeFeedCollectionView registerNib:[UINib nibWithNibName:@"GridViewCell" bundle:nil] forCellWithReuseIdentifier:@"GridItemCell"];

}

-(void)viewWillAppear
{
//Create the layout objects

         self.grideLayout = [[GridFlowLayOut alloc]init];
    self.tableViewLayout = [[TableViewFlowLayOut alloc]init];

//Set the first layout to what it should be 

    [self.tradeFeedCollectionView setCollectionViewLayout:self.tableViewLayout];

}

Right - now to change between the layouts with some animation. 对-现在可以在带有动画的布局之间进行切换。 This is actually very easy to do and only needs a few lines of code - 这实际上很容易做到,只需要几行代码-

I called this code in a button method in viewController.m 我在viewController.m中的按钮方法中调用了此代码

-(void)changeViewLayoutButtonPressed
{
//BOOl value to switch between layouts 

    self.changeLayout = !self.changeLayout;

    if (self.changeLayout){
    [self.tradeFeedCollectionView setCollectionViewLayout:self.grideLayout animated:YES];

    }

    else {

          [self.tradeFeedCollectionView setCollectionViewLayout:self.tableViewLayout animated:YES];
    }
}

And lastly in cellForItemAtIndexPath 最后在cellForItemAtIndexPath

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{   static NSString *tableCellIdentifier = @"TableItemCell";
    static NSString *gridCellIdentifier = @"GridItemCell";

//BOOL used to detect which layout is active
    if (self.gridLayoutActive == NO){

        CustomCollectionCellClass *tableItemCell = [collectionView dequeueReusableCellWithReuseIdentifier:tableCellIdentifier forIndexPath:indexPath];

    //Setup the cell

    }
        return tableItemCell;
}else
    {

        CustomCollectionCellClass *gridItemCell= [collectionView dequeueReusableCellWithReuseIdentifier:gridCellIdentifier forIndexPath:indexPath];

    //Setup the cell

    }

    return gridItemCell;
    }
        return nil;

}

Of course you will need to conform to the other UICollectionView delegates and setup the remaining stuff. 当然,您将需要符合其他UICollectionView委托并设置其余内容。

This actually took me a while to figure out. 这实际上花了我一段时间。 I really hope it helps others out there. 我真的希望它能帮助其他人。 If anyone wants a demo project - I'll happily create one and upload to GitHub. 如果有人想要一个演示项目,我将很高兴创建一个演示项目并上传到GitHub。

For anyone new to UICollectionViews I highly recommend reading Apple's programming guide on the subject - it was this document which lead me to this solution. 对于UICollectionViews的新手,我强烈建议阅读Apple对此主题的编程指南-正是此文档使我找到了该解决方案。

Reference: https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/CollectionViewPGforIOS/Introduction/Introduction.html 参考: https : //developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/CollectionViewPGforIOS/Introduction/Introduction.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM