How to create horizontally dynamic UICollectionVie

2020-04-18 03:40发布

问题:

Hey I'm trying display a set of "tags" in a view controller using collection view cells but I'm having trouble finding a way to make them be able to dynamically resizable depending on the length of the string.

Right now the individual cells are statically sized so whenever a String that populates the cell with characters exceeding the size of the cell, it goes into the second line. I want it so that the cell can change length depending on the length of the String. So if it's the tag "#Vegan", it will automatically resize so that the tag isn't that big. Likewise, if it's a longer string like "#LaptopFriendly", it will become horizontally longer to accommodate the string and not use the second line. The vertical length can stay fixed. Thank you!

UPDATE (interface builder settings when I run into errors using Rob's code):

Simulator screenshot:

回答1:

You need unambiguous constraints between your label and the cell (e.g. leading, trailing, top, and bottom constraints):

Then you can use UICollectionViewFlowLayoutAutomaticSize for the itemSize of your collectionViewLayout. Don't forget to set estimatedItemSize, too, which enables automatically resizing cells:

override func viewDidLoad() {
    super.viewDidLoad()

    let layout = collectionView?.collectionViewLayout as! UICollectionViewFlowLayout
    layout.itemSize = UICollectionViewFlowLayoutAutomaticSize
    layout.estimatedItemSize = CGSize(width: 100, height: 40)
}

That yields:



回答2:

You can calculate the lengths of the texts ahead of time, feed them into an array accessible by your collectionView and use them them to construct the size of the cell.

//Create vars
NSArray * texts = @[@"Short",@"Something Long",@"Something Really Long"];
NSMutableArray * lengths = [NSMutableArray new];
float padding = 30.0f;

//Create dummy label
UILabel * label = [UILabel new];
label.frame = CGRectZero;
label.font = [UIFont systemFontOfSize:20.0f weight:UIFontWeightBold];

//loop through the texts
for (NSString * string in texts){

    //set text
    label.text = string;

    //calculate length + add padding
    float length = [label.text boundingRectWithSize:label.frame.size
                                            options:NSStringDrawingUsesLineFragmentOrigin
                                         attributes:@{NSFontAttributeName:label.font}
                                            context:nil].size.width + padding;
    //save value into array as NSNumber
    [lengths addObject:@(length)];
}

//drop label
label = nil;

Create the size of the cell using some code like this:

return CGSizeMake(lengths[indexPath.row], 100.0f);