UICollectionView:根据 UIButton 的文本宽度为每个单元格应用动态宽度
UICollectionView: Apply dynamic width for each cell according to UIButton's text width
我知道有很多关于这个问题的类似话题。虽然,我先试过了,但没有解决我的问题。
如下图所示,我尝试使用 UICollectionView 应用水平滚动视图。每个单元格都包含一个具有动态文本长度的 UIButton。
问题是某些单元格的宽度是 wrong/short。我尝试先获取每个 NSString 文本大小的解决方案,然后在 sizeForItemAt
委托方法中设置它。但是效果不佳,即使我手动添加了填充值,文本仍在缩小 CGSize sizeWithPadding = CGSizeMake(size.width + 30, 40)
.
经过几个小时的搜索和测试,仍然不知道如何使它正确。欢迎任何建议。
数据源=NSString数组
[NSMutableArray arrayWithObjects:@"All", @"Computer programming", @"Taylor Swift", @"Movies", @"Airplane", @"Basketball", @"Iron man", @"Football", @"ABC", @"Gong Fu", @"Dong Hua", nil]
一个 UIView 作为 collectionView 的容器。
- (void)setViews {
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
layout.minimumLineSpacing = CGFLOAT_MAX;
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
self.collectionView.translatesAutoresizingMaskIntoConstraints = false;
self.collectionView.backgroundColor = UIColor.systemBackgroundColor;
_collectionView.dataSource = self;
_collectionView.delegate = self;
[_collectionView registerClass:MenuBarCell.class forCellWithReuseIdentifier:menuBarCellID];
[self addSubview:self.collectionView];
[self.collectionView.topAnchor constraintEqualToAnchor:self.topAnchor].active = true;
[self.collectionView.leadingAnchor constraintEqualToAnchor:self.leadingAnchor].active = true;
[self.collectionView.trailingAnchor constraintEqualToAnchor:self.trailingAnchor].active = true;
[self.collectionView.heightAnchor constraintEqualToAnchor:self.heightAnchor].active = true;
}
# pragma mark - collectionView dataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return _menuBarArray.count;
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
MenuBarCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:menuBarCellID forIndexPath:indexPath];
NSString *model = _menuBarArray[indexPath.item];
[cell configure:model];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGSize size = [self.menuBarArray[indexPath.item] sizeWithAttributes:NULL];
NSLog(@"size: width = %f", size.width);
CGSize sizeWithPadding = CGSizeMake(size.width + 30, 40);
return sizeWithPadding;
}
我的 UICollectionView 自定义单元格
- (void)setViews {
[super setViews];
self.contentView.backgroundColor = UIColor.systemYellowColor;
// create buttons
_button = [UIButton buttonWithType:UIButtonTypeCustom];
_button.translatesAutoresizingMaskIntoConstraints = false;
_button.layer.cornerRadius = 15;
_button.layer.masksToBounds = true;
[_button setBackgroundColor:[UIColor colorWithWhite:0.92 alpha:1]];
[_button setTitleColor:UIColor.labelColor forState:UIControlStateNormal];
[_button setTitleColor:UIColor.buttonTitleHighlighted forState:UIControlStateHighlighted];
[self.contentView addSubview:_button];
// set constraints
[_button.centerXAnchor constraintEqualToAnchor:self.contentView.centerXAnchor].active = true;
[_button.centerYAnchor constraintEqualToAnchor:self.contentView.centerYAnchor].active = true;
[_button.widthAnchor constraintEqualToAnchor:self.contentView.widthAnchor].active = true;
[_button.heightAnchor constraintLessThanOrEqualToAnchor:self.contentView.heightAnchor].active = true;
}
- (void)configure: (NSString *)model {
[_button setTitle:model forState:UIControlStateNormal];
}
有些地方不对...
摆脱 sizeForItemAtIndexPath
方法 -- 您想要使用自动调整单元格大小。
接下来,您没有显示用于约束“容器”视图的代码,但我认为它是这样的:
- (void)viewDidLoad {
[super viewDidLoad];
menuBarView = [MenuBarView new];
menuBarView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:menuBarView];
UILayoutGuide *g = [self.view safeAreaLayoutGuide];
[NSLayoutConstraint activateConstraints:@[
[menuBarView.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:0.0],
[menuBarView.trailingAnchor constraintEqualToAnchor:g.trailingAnchor constant:0.0],
[menuBarView.topAnchor constraintEqualToAnchor:g.topAnchor constant:4.0],
[menuBarView.heightAnchor constraintEqualToConstant:42.0],
]];
}
您的 UICollectionViewFlowLayout
应该是这样的:
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
// spacing between cells
layout.minimumLineSpacing = 8.0;
// prevents last cell from being cut-off
layout.minimumInteritemSpacing = layout.minimumLineSpacing;
// must have an estimated size
// inconsequential, but needs to be less than expectd
layout.estimatedItemSize = CGSizeMake(10, 10);
并像这样配置您的手机 class:
// I don't know what your super-class is...
//[super setViews];
self.contentView.backgroundColor = UIColor.systemYellowColor;
// create buttons
_button = [UIButton buttonWithType:UIButtonTypeCustom];
_button.translatesAutoresizingMaskIntoConstraints = false;
_button.layer.cornerRadius = 15;
_button.layer.masksToBounds = true;
// give the button a little top / leading / bottom / trailing "padding"
_button.contentEdgeInsets = UIEdgeInsetsMake(8, 20, 8, 20);
[_button setBackgroundColor:[UIColor colorWithWhite:0.92 alpha:1]];
[_button setTitleColor:UIColor.labelColor forState:UIControlStateNormal];
[_button setTitleColor:UIColor.whiteColor forState:UIControlStateHighlighted];
[self.contentView addSubview:_button];
// set constraints
UIView *g = self.contentView;
[NSLayoutConstraint activateConstraints:@[
[_button.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:0.0],
[_button.trailingAnchor constraintEqualToAnchor:g.trailingAnchor constant:0.0],
[_button.topAnchor constraintEqualToAnchor:g.topAnchor constant:2.0],
[_button.bottomAnchor constraintEqualToAnchor:g.bottomAnchor constant:-2.0],
]];
结果应该如下所示(我给“容器”视图设置了蓝色背景以便我们可以看到它):
我知道有很多关于这个问题的类似话题。虽然,我先试过了,但没有解决我的问题。
如下图所示,我尝试使用 UICollectionView 应用水平滚动视图。每个单元格都包含一个具有动态文本长度的 UIButton。
问题是某些单元格的宽度是 wrong/short。我尝试先获取每个 NSString 文本大小的解决方案,然后在 sizeForItemAt
委托方法中设置它。但是效果不佳,即使我手动添加了填充值,文本仍在缩小 CGSize sizeWithPadding = CGSizeMake(size.width + 30, 40)
.
经过几个小时的搜索和测试,仍然不知道如何使它正确。欢迎任何建议。
数据源=NSString数组
[NSMutableArray arrayWithObjects:@"All", @"Computer programming", @"Taylor Swift", @"Movies", @"Airplane", @"Basketball", @"Iron man", @"Football", @"ABC", @"Gong Fu", @"Dong Hua", nil]
一个 UIView 作为 collectionView 的容器。
- (void)setViews {
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
layout.minimumLineSpacing = CGFLOAT_MAX;
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
self.collectionView.translatesAutoresizingMaskIntoConstraints = false;
self.collectionView.backgroundColor = UIColor.systemBackgroundColor;
_collectionView.dataSource = self;
_collectionView.delegate = self;
[_collectionView registerClass:MenuBarCell.class forCellWithReuseIdentifier:menuBarCellID];
[self addSubview:self.collectionView];
[self.collectionView.topAnchor constraintEqualToAnchor:self.topAnchor].active = true;
[self.collectionView.leadingAnchor constraintEqualToAnchor:self.leadingAnchor].active = true;
[self.collectionView.trailingAnchor constraintEqualToAnchor:self.trailingAnchor].active = true;
[self.collectionView.heightAnchor constraintEqualToAnchor:self.heightAnchor].active = true;
}
# pragma mark - collectionView dataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return _menuBarArray.count;
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
MenuBarCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:menuBarCellID forIndexPath:indexPath];
NSString *model = _menuBarArray[indexPath.item];
[cell configure:model];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGSize size = [self.menuBarArray[indexPath.item] sizeWithAttributes:NULL];
NSLog(@"size: width = %f", size.width);
CGSize sizeWithPadding = CGSizeMake(size.width + 30, 40);
return sizeWithPadding;
}
我的 UICollectionView 自定义单元格
- (void)setViews {
[super setViews];
self.contentView.backgroundColor = UIColor.systemYellowColor;
// create buttons
_button = [UIButton buttonWithType:UIButtonTypeCustom];
_button.translatesAutoresizingMaskIntoConstraints = false;
_button.layer.cornerRadius = 15;
_button.layer.masksToBounds = true;
[_button setBackgroundColor:[UIColor colorWithWhite:0.92 alpha:1]];
[_button setTitleColor:UIColor.labelColor forState:UIControlStateNormal];
[_button setTitleColor:UIColor.buttonTitleHighlighted forState:UIControlStateHighlighted];
[self.contentView addSubview:_button];
// set constraints
[_button.centerXAnchor constraintEqualToAnchor:self.contentView.centerXAnchor].active = true;
[_button.centerYAnchor constraintEqualToAnchor:self.contentView.centerYAnchor].active = true;
[_button.widthAnchor constraintEqualToAnchor:self.contentView.widthAnchor].active = true;
[_button.heightAnchor constraintLessThanOrEqualToAnchor:self.contentView.heightAnchor].active = true;
}
- (void)configure: (NSString *)model {
[_button setTitle:model forState:UIControlStateNormal];
}
有些地方不对...
摆脱 sizeForItemAtIndexPath
方法 -- 您想要使用自动调整单元格大小。
接下来,您没有显示用于约束“容器”视图的代码,但我认为它是这样的:
- (void)viewDidLoad {
[super viewDidLoad];
menuBarView = [MenuBarView new];
menuBarView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:menuBarView];
UILayoutGuide *g = [self.view safeAreaLayoutGuide];
[NSLayoutConstraint activateConstraints:@[
[menuBarView.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:0.0],
[menuBarView.trailingAnchor constraintEqualToAnchor:g.trailingAnchor constant:0.0],
[menuBarView.topAnchor constraintEqualToAnchor:g.topAnchor constant:4.0],
[menuBarView.heightAnchor constraintEqualToConstant:42.0],
]];
}
您的 UICollectionViewFlowLayout
应该是这样的:
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
// spacing between cells
layout.minimumLineSpacing = 8.0;
// prevents last cell from being cut-off
layout.minimumInteritemSpacing = layout.minimumLineSpacing;
// must have an estimated size
// inconsequential, but needs to be less than expectd
layout.estimatedItemSize = CGSizeMake(10, 10);
并像这样配置您的手机 class:
// I don't know what your super-class is...
//[super setViews];
self.contentView.backgroundColor = UIColor.systemYellowColor;
// create buttons
_button = [UIButton buttonWithType:UIButtonTypeCustom];
_button.translatesAutoresizingMaskIntoConstraints = false;
_button.layer.cornerRadius = 15;
_button.layer.masksToBounds = true;
// give the button a little top / leading / bottom / trailing "padding"
_button.contentEdgeInsets = UIEdgeInsetsMake(8, 20, 8, 20);
[_button setBackgroundColor:[UIColor colorWithWhite:0.92 alpha:1]];
[_button setTitleColor:UIColor.labelColor forState:UIControlStateNormal];
[_button setTitleColor:UIColor.whiteColor forState:UIControlStateHighlighted];
[self.contentView addSubview:_button];
// set constraints
UIView *g = self.contentView;
[NSLayoutConstraint activateConstraints:@[
[_button.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:0.0],
[_button.trailingAnchor constraintEqualToAnchor:g.trailingAnchor constant:0.0],
[_button.topAnchor constraintEqualToAnchor:g.topAnchor constant:2.0],
[_button.bottomAnchor constraintEqualToAnchor:g.bottomAnchor constant:-2.0],
]];
结果应该如下所示(我给“容器”视图设置了蓝色背景以便我们可以看到它):