如何创建水平动态的 UICollectionView 单元格? Swift
How to create horizontally dynamic UICollectionView cells? Swift
嘿,我正在尝试使用集合视图单元在视图控制器中显示一组 "tags",但我无法找到一种方法使它们能够根据视图的长度动态调整大小细绳。
现在,单个单元格的大小是静态的,所以每当一个字符串用超过单元格大小的字符填充单元格时,它就会进入第二行。我想要它,以便单元格可以根据字符串的长度改变长度。所以如果它是标签“#Vegan”,它会自动调整大小,这样标签就不会那么大。同样,如果它是一个较长的字符串,如“#LaptopFriendly”,它将在水平方向上变长以容纳该字符串并且不使用第二行。垂直长度可以保持固定。谢谢!
更新(当我 运行 使用 Rob 的代码出错时的界面构建器设置):
模拟器截图:
您可以提前计算文本的长度,将它们提供给您的 collectionView 可访问的数组,并使用它们来构造单元格的大小。
//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;
使用如下代码创建单元格大小:
return CGSizeMake(lengths[indexPath.row], 100.0f);
您的标签和单元格之间需要明确的约束(例如前导、尾随、顶部和底部约束):
然后您可以将 UICollectionViewFlowLayoutAutomaticSize
用于 collectionViewLayout
的 itemSize
。不要忘记设置 estimatedItemSize
,这样可以自动调整单元格大小:
override func viewDidLoad() {
super.viewDidLoad()
let layout = collectionView?.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = UICollectionViewFlowLayoutAutomaticSize
layout.estimatedItemSize = CGSize(width: 100, height: 40)
}
产生:
嘿,我正在尝试使用集合视图单元在视图控制器中显示一组 "tags",但我无法找到一种方法使它们能够根据视图的长度动态调整大小细绳。
现在,单个单元格的大小是静态的,所以每当一个字符串用超过单元格大小的字符填充单元格时,它就会进入第二行。我想要它,以便单元格可以根据字符串的长度改变长度。所以如果它是标签“#Vegan”,它会自动调整大小,这样标签就不会那么大。同样,如果它是一个较长的字符串,如“#LaptopFriendly”,它将在水平方向上变长以容纳该字符串并且不使用第二行。垂直长度可以保持固定。谢谢!
更新(当我 运行 使用 Rob 的代码出错时的界面构建器设置):
模拟器截图:
您可以提前计算文本的长度,将它们提供给您的 collectionView 可访问的数组,并使用它们来构造单元格的大小。
//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;
使用如下代码创建单元格大小:
return CGSizeMake(lengths[indexPath.row], 100.0f);
您的标签和单元格之间需要明确的约束(例如前导、尾随、顶部和底部约束):
然后您可以将 UICollectionViewFlowLayoutAutomaticSize
用于 collectionViewLayout
的 itemSize
。不要忘记设置 estimatedItemSize
,这样可以自动调整单元格大小:
override func viewDidLoad() {
super.viewDidLoad()
let layout = collectionView?.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = UICollectionViewFlowLayoutAutomaticSize
layout.estimatedItemSize = CGSize(width: 100, height: 40)
}
产生: