[ios] UICollectionView - dynamic cell height?

Here is a Ray Wenderlich tutorial that shows you how to use AutoLayout to dynamically size UITableViewCells. I would think it would be the same for UICollectionViewCell.

Basically, though, you end up dequeueing and configuring a prototype cell and grabbing its height. After reading this article, I decided to NOT implement this method and just write some clear, explicit sizing code.

Here's what I consider the "secret sauce" for the entire article:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return [self heightForBasicCellAtIndexPath:indexPath];
}

- (CGFloat)heightForBasicCellAtIndexPath:(NSIndexPath *)indexPath {
    static RWBasicCell *sizingCell = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sizingCell = [self.tableView dequeueReusableCellWithIdentifier:RWBasicCellIdentifier];
    });

    [self configureBasicCell:sizingCell atIndexPath:indexPath];
    return [self calculateHeightForConfiguredSizingCell:sizingCell];
}

- (CGFloat)calculateHeightForConfiguredSizingCell:(UITableViewCell *)sizingCell {
    [sizingCell setNeedsLayout];
    [sizingCell layoutIfNeeded];

    CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
    return size.height + 1.0f; // Add 1.0f for the cell separator height
}


EDIT: I did some research into your crash and decided that there is no way to get this done without a custom XIB. While that is a bit frustrating, you should be able to cut and paste from your Storyboard to a custom, empty XIB.

Once you've done that, code like the following will get you going:

//  ViewController.m
#import "ViewController.h"
#import "CollectionViewCell.h"
@interface ViewController () <UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout> {

}
@property (weak, nonatomic) IBOutlet CollectionViewCell *cell;
@property (weak, nonatomic) IBOutlet UICollectionView   *collectionView;
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor lightGrayColor];
    [self.collectionView registerNib:[UINib nibWithNibName:@"CollectionViewCell" bundle:nil] forCellWithReuseIdentifier:@"cell"];
}
- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    NSLog(@"viewDidAppear...");
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return 50;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
    return 10.0f;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
    return 10.0f;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    return [self sizingForRowAtIndexPath:indexPath];
}
- (CGSize)sizingForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *title                  = @"This is a long title that will cause some wrapping to occur. This is a long title that will cause some wrapping to occur.";
    static NSString *subtitle               = @"This is a long subtitle that will cause some wrapping to occur. This is a long subtitle that will cause some wrapping to occur.";
    static NSString *buttonTitle            = @"This is a really long button title that will cause some wrapping to occur.";
    static CollectionViewCell *sizingCell   = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sizingCell                          = [[NSBundle mainBundle] loadNibNamed:@"CollectionViewCell" owner:self options:nil][0];
    });
    [sizingCell configureWithTitle:title subtitle:[NSString stringWithFormat:@"%@: Number %d.", subtitle, (int)indexPath.row] buttonTitle:buttonTitle];
    [sizingCell setNeedsLayout];
    [sizingCell layoutIfNeeded];
    CGSize cellSize = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
    NSLog(@"cellSize: %@", NSStringFromCGSize(cellSize));
    return cellSize;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *title                  = @"This is a long title that will cause some wrapping to occur. This is a long title that will cause some wrapping to occur.";
    static NSString *subtitle               = @"This is a long subtitle that will cause some wrapping to occur. This is a long subtitle that will cause some wrapping to occur.";
    static NSString *buttonTitle            = @"This is a really long button title that will cause some wrapping to occur.";
    CollectionViewCell *cell                = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
    [cell configureWithTitle:title subtitle:[NSString stringWithFormat:@"%@: Number %d.", subtitle, (int)indexPath.row] buttonTitle:buttonTitle];
    return cell;
}
@end

The code above (along with a very basic UICollectionViewCell subclass and associated XIB) gives me this:

enter image description here

Examples related to ios

Adding a UISegmentedControl to UITableView Crop image to specified size and picture location Undefined Symbols error when integrating Apptentive iOS SDK via Cocoapods Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Autoresize View When SubViews are Added Warp \ bend effect on a UIView? Speech input for visually impaired users without the need to tap the screen make UITableViewCell selectable only while editing Xcode 12, building for iOS Simulator, but linking in object file built for iOS, for architecture arm64

Examples related to swift

Make a VStack fill the width of the screen in SwiftUI Xcode 10.2.1 Command PhaseScriptExecution failed with a nonzero exit code Command CompileSwift failed with a nonzero exit code in Xcode 10 Convert Json string to Json object in Swift 4 iOS Swift - Get the Current Local Time and Date Timestamp Xcode 9 Swift Language Version (SWIFT_VERSION) How do I use Safe Area Layout programmatically? How can I use String substring in Swift 4? 'substring(to:)' is deprecated: Please use String slicing subscript with a 'partial range from' operator Safe Area of Xcode 9 The use of Swift 3 @objc inference in Swift 4 mode is deprecated?

Examples related to uicollectionview

How to set UICollectionViewCell Width and Height programmatically How to make a simple collection view with Swift How to set cell spacing and UICollectionView - UICollectionViewFlowLayout size ratio? UICollectionView - dynamic cell height? UICollectionView Self Sizing Cells with Auto Layout Fatal error: unexpectedly found nil while unwrapping an Optional values Paging UICollectionView by cells, not screen UICollectionView - Horizontal scroll, horizontal layout? UICollectionView current visible cell index Creating a UICollectionView programmatically