سؤال

I've been reading online tutorials on UICollectionView with different layouts. Also looked at a lot of SO Questions on the subject. 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. I am displaying data in a UITableView which includes:1 UIImageView and three UILabels in each cell. 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.

It suddenly dawned on me that I needed to use a UICollectionView to change between these two cells and ditch the UITableView completely. Tapping the button again, would switch back to the last state (Grid or UITableView style)

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. I think I could use a Apple's pre-made UICollectionViewFlowLayout and just tweak it a little.

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.

  • First thing is create the customCells in IB - creating the xib files.
  • 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.

  • Create two (or more if needed) classes that subclass 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.

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. (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

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

-(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

-(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.

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.

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.

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top