Join the social network of Tech Nerds, increase skill rank, get work, manage projects...
 
  • UICollectionViewCell with dynamic cell height

    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 1.95k
    Comment on it

    Sometimes we require dynamic height of UICollectionViewcell according to text of our label like this:

     

    To get output like this do following steps. 

     

    Go to your storyboard, from "object library" drag a collectionView to your view controller.Now place a title and description label on collection’s cell.

     

    Set CollectionView's background color otherwise it will only show a black screen when you will run the app.

    create a new file -> Cocoa touch Class -> next -> UICollectionViewCell(DemoCollectionViewCell in this case).

     

    Now come to storyboard select your collectionViewCell and go to its identity inspector and give class name “DemoCollectionViewCell” and now come to its attribute inspector and set identifier “DemoCollectionViewCell”.

     

                                         

    Select Description label and set "Line Breaks" to "Word Wrap" and "Lines" to "0"

     

    make IBOutlet of “title” and “Description” in “DemoCollectionViewcell”

    @property (weak, nonatomic) IBOutlet UILabel *titleLbl;
    @property (weak, nonatomic) IBOutlet UILabel *descriptionLbl;

     

    Now come to your viewController class and declare 2 array

    NSArray *descriptionArray;//to hold description array content
    NSMutableArray *titleArray;// we will use it to store size of text in description array

     

    Now in your “viewDidLoad” initialize both array.

    titleArray = [[NSMutableArray alloc] init];
    descriptionArray = [[NSArray alloc] init];
    descriptionArray = @[@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",@"1",@"2",@"3",@"4",@"abcdefghijklmnopqrstuvwxyz",@"5",@"7"];

     

    Now in delegate method of UICollectionView put following line of code.

    -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
        return descriptionArray.count;
    }
    
    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
        DemoCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"DemoCollectionViewCell" forIndexPath:indexPath];
        cell.descriptionLbl.text = [descriptionArray objectAtIndex:indexPath.row];
        return cell;
    }

     

    Now run your app. You will get output like this:

     

    Here we have to increase the size of the cell which has large text and also have to adjust alignment of cell so that it’s UI look good.

    To do this we will first calculate the size of text,then we will increase height this cell so that it will show whole text .

    For this follow these steps:

    Define a maxNumberofCell above your @interface

    And then calculate size for each text of descriptionArray, to calculate height of cell.

    #define maxNumberOfCell 2 // you can change it according to number of cell you want to display in one row(in this case take 2)
    -(void)setHeightForEachItem{
        
        CGFloat width = (self.view.frame.size.width/maxNumberOfCell)-11;//set the width of your collection view cell
        for (id object in descriptionArray) {
            CGSize lableSize = [object sizeWithFont:[UIFont fontWithName:@"Arial" size:16]constrainedToSize:CGSizeMake(width, 500)];//here we will give font style (this font and storyboard descripionLbl should be same)
            lableSize.width = width;
            NSValue *labelRect  = [NSValue valueWithCGSize:lableSize];
            [titleArray addObject:labelRect];// we add each size of text in titleArray
        }
        
        int length = (int)titleArray.count/maxNumberOfCell;
        int len = (int)titleArray.count%maxNumberOfCell;
        int lengthForLoop;
        if (len > 0) {
            lengthForLoop = length + 1;
        }
        else{
            lengthForLoop = length;
        }
        [self calulateSizeForRow:lengthForLoop withWidth:width withNumberOfObject: maxNumberOfCell];
    }
    
    
    -(void)calulateSizeForRow:(int)len withWidth:(CGFloat)width withNumberOfObject:(int)number{
     //len will define number of time for loop will run. width is UICollectionViewCells width.
        int val = number;
        for (int i=0; i < len; i++) {
            if (i == len-1) {
               // here we will check for last row of collectionViewCell
                if ((int)titleArray.count%maxNumberOfCell != 0) {
                    number = (int)titleArray.count%maxNumberOfCell;
                }
            }
            NSMutableArray *subArr = [[titleArray subarrayWithRange:NSMakeRange(i*val, number)] mutableCopy];//i*val is for location of array and number is for its length.
            CGFloat maxHeight = [self find_min:subArr];// this will be the highest height of cell in particular row.
            [subArr enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                NSValue *labelRect  = obj;
                CGSize size = [labelRect CGSizeValue];
                size.height = maxHeight+65;(height of title label + title labels top space + title labels bottom space)// use can change this according to your spacing requirement.
                [titleArray replaceObjectAtIndex:[titleArray indexOfObject:labelRect] withObject:[NSValue valueWithCGSize:size]];//here we are replacing old height to new height of cell,according to text of cell.
            }];
        }
    }
    
    - (CGFloat)find_min:(NSArray *)heights{// this function will return max height.
        
        __block CGFloat maxHeight = 0;
        [heights enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            NSValue *labelRect  = obj;
            CGSize size = [labelRect CGSizeValue];
            if (maxHeight < size.height) {
                maxHeight = size.height;
            }
            
        }];
        return maxHeight;
    }
    

    Now the give that calculates size to “sizeForItemAtIndexPath” method.

    - (CGSize)collectionView:(UICollectionView *)collectionView
                      layout:(UICollectionViewLayout *)collectionViewLayout
      sizeForItemAtIndexPath:(NSIndexPath *)indexPath
    {
            CGSize size = [[titleArray objectAtIndex:indexPath.item] CGSizeValue];
            return size;
    }
    

     

    Edit your "viewDidLoad" 

    - (void)viewDidLoad {
        [super viewDidLoad];
        titleArray = [[NSMutableArray alloc] init];
        descriptionArray = [[NSArray alloc] init];
        descriptionArray = @[@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",@"1",@"2",@"3",@"4",@"abcdefghijklmnopqrstuvwxyz",@"5",@"7"];
        [self setHeightForEachItem];
        //Do any additional setup after loading the view, typically from a nib.
    }

     

    Now run your app,you will see output like this.

     

    Last row is not align here,

    to align last row of UICollectionViewCell Add this method to your viewController

    - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section{
        return 22;// you can adjust size according to your cells alignment.
    }
    

    Now run your app.

 0 Comment(s)

Sign In
                           OR                           
                           OR                           
Register

Sign up using

                           OR                           
Forgot Password
Fill out the form below and instructions to reset your password will be emailed to you:
Reset Password
Fill out the form below and reset your password: