根据文本调整单元格宽度 - UICollectionView - iOS
Adjust cell width based on text - UICollectionView - iOS
我有一个 iOS 应用程序,其中 UICollectionView
水平显示单元格。在每个单元格中,我都添加了一个简单的标签(目前)。这些标签显示名称,有时名称很短,这很好...但是...有时名称很长,因此被截断,因为它们无法正确适应集合视图单元格的宽度。
有没有办法动态调整 cell/label 的宽度,以便正确显示名称文本?
我正在尝试使用这种方法:
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(106.f, 60.f);
}
但是我上面的方法主要有两个问题:
- 如何通过此方法访问单元格标签? (这样我就可以得到它的高度)。
- 我如何实际计算 cell/label 的宽度?
感谢您的宝贵时间,
段
您无法访问标签,但可以访问用于填充标签的数据。有了它,您可以获得标签的高度和宽度:
CGRect labelRect = [text
boundingRectWithSize:CGSizeMake(MAX WIDTH OF YOUR LABEL, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{
NSFontAttributeName : [FONT OF YOUR LABEL]
}
context:nil];
我在 TableView
中做了同样的事情 - 希望你可以将此逻辑用于 collectionView
celllabelWidth - width of the Cell, you can get it from cellForItemAtIndexPath
celllabelWidth = cell.lblEvent.frame.size.width;
- (CGFloat)findHeightForText:(NSString *)text havingWidth:(CGFloat)widthValue andFont:(UIFont *)font {
CGSize size = CGSizeZero;
if (text) {
//iOS 7
CGRect frame = [text boundingRectWithSize:CGSizeMake(widthValue, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{ NSFontAttributeName:font } context:nil];
size = CGSizeMake(frame.size.width, frame.size.height);
}
return size.height;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat heightOfRow = 86.0;
NSString *yourBlog = [[self.arrevents objectAtIndex:indexPath.row ] valueForKey:@"info"];
heightOfBlog = [self findHeightForText:yourBlog havingWidth:celllabelWidth andFont:[UIFont fontWithName:@"HelveticaNeue" size:14.0]];
heightOfRow += heightOfBlog + 10;
(long)indexPath.row,heightOfRow);
return heightOfRow;
}
祝一切顺利:)
我在集合视图中使用以下代码做了同样的事情:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGSize size1 = CGSizeMake(MAX_WIDTH_OF_STRING, [self height:YOUR_STRING];
return size1;
}
-(float)height :(NSString*)string
{
UIFont *newFont = [[Util sharedUtil] fontOfType:FONT_HELVETICA_LT bold:NO size:INTERFACE_IS_PHONE?12:FONT_SIZE_LARGE_CELL];
NSDictionary *arialdict = [NSDictionary dictionaryWithObject:newFont forKey:NSFontAttributeName];
NSMutableAttributedString *message = [[NSMutableAttributedString alloc] initWithString:string attributes:arialdict];
NSAttributedString *attributedText = message;
CGRect rect = [attributedText boundingRectWithSize:(CGSize)
{INTERFACE_IS_PHONE?135:220, MAXFLOAT}
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
//you need to specify the some width, height will be calculated
CGSize requiredSize = rect.size;
return MAX(requiredSize.height,INTERFACE_IS_PHONE?20:30);
}
希望对你有帮助。
感谢大家的发帖,最终对我有用的解决方案是混合了你们所有的解决方案和一些额外的 "tinkering":
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
// Get the user name and profile name strings.
NSString *user_label = [NSString stringWithFormat:@"%@", [user_data[indexPath.row] objectAtIndex:0]];
NSString *name_label = [NSString stringWithFormat:@"%@", [user_data[indexPath.row] objectAtIndex:1]];
// Calculate the contact text widths.
NSDictionary *attributes = @{NSFontAttributeName:[UIFont fontWithName:@"SFUIDisplay-Thin" size:20.0f]};
CGRect rect = [user_label boundingRectWithSize:CGSizeMake(MAXFLOAT, 60) options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];
CGRect rect_two = [name_label boundingRectWithSize:CGSizeMake(MAXFLOAT, 60) options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];
// Add the other cell objects width to
// the biggest calculated text width.
CGFloat row_width = 0;
if (rect.size.width > rect_two.size.width) {
row_width = (rect.size.width + 55);
}
else {
row_width = (rect_two.size.width + 55);
}
// Only return the generated width if
// it is bigger than the original width.
if (row_width > 106) {
return CGSizeMake(row_width, 60.f);
}
else {
return CGSizeMake(106, 60.f);
}
}
我有一个 iOS 应用程序,其中 UICollectionView
水平显示单元格。在每个单元格中,我都添加了一个简单的标签(目前)。这些标签显示名称,有时名称很短,这很好...但是...有时名称很长,因此被截断,因为它们无法正确适应集合视图单元格的宽度。
有没有办法动态调整 cell/label 的宽度,以便正确显示名称文本?
我正在尝试使用这种方法:
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(106.f, 60.f);
}
但是我上面的方法主要有两个问题:
- 如何通过此方法访问单元格标签? (这样我就可以得到它的高度)。
- 我如何实际计算 cell/label 的宽度?
感谢您的宝贵时间,
段
您无法访问标签,但可以访问用于填充标签的数据。有了它,您可以获得标签的高度和宽度:
CGRect labelRect = [text
boundingRectWithSize:CGSizeMake(MAX WIDTH OF YOUR LABEL, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{
NSFontAttributeName : [FONT OF YOUR LABEL]
}
context:nil];
我在 TableView
中做了同样的事情 - 希望你可以将此逻辑用于 collectionView
celllabelWidth - width of the Cell, you can get it from cellForItemAtIndexPath
celllabelWidth = cell.lblEvent.frame.size.width;
- (CGFloat)findHeightForText:(NSString *)text havingWidth:(CGFloat)widthValue andFont:(UIFont *)font {
CGSize size = CGSizeZero;
if (text) {
//iOS 7
CGRect frame = [text boundingRectWithSize:CGSizeMake(widthValue, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{ NSFontAttributeName:font } context:nil];
size = CGSizeMake(frame.size.width, frame.size.height);
}
return size.height;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat heightOfRow = 86.0;
NSString *yourBlog = [[self.arrevents objectAtIndex:indexPath.row ] valueForKey:@"info"];
heightOfBlog = [self findHeightForText:yourBlog havingWidth:celllabelWidth andFont:[UIFont fontWithName:@"HelveticaNeue" size:14.0]];
heightOfRow += heightOfBlog + 10;
(long)indexPath.row,heightOfRow);
return heightOfRow;
}
祝一切顺利:)
我在集合视图中使用以下代码做了同样的事情:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGSize size1 = CGSizeMake(MAX_WIDTH_OF_STRING, [self height:YOUR_STRING];
return size1;
}
-(float)height :(NSString*)string
{
UIFont *newFont = [[Util sharedUtil] fontOfType:FONT_HELVETICA_LT bold:NO size:INTERFACE_IS_PHONE?12:FONT_SIZE_LARGE_CELL];
NSDictionary *arialdict = [NSDictionary dictionaryWithObject:newFont forKey:NSFontAttributeName];
NSMutableAttributedString *message = [[NSMutableAttributedString alloc] initWithString:string attributes:arialdict];
NSAttributedString *attributedText = message;
CGRect rect = [attributedText boundingRectWithSize:(CGSize)
{INTERFACE_IS_PHONE?135:220, MAXFLOAT}
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
//you need to specify the some width, height will be calculated
CGSize requiredSize = rect.size;
return MAX(requiredSize.height,INTERFACE_IS_PHONE?20:30);
}
希望对你有帮助。
感谢大家的发帖,最终对我有用的解决方案是混合了你们所有的解决方案和一些额外的 "tinkering":
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
// Get the user name and profile name strings.
NSString *user_label = [NSString stringWithFormat:@"%@", [user_data[indexPath.row] objectAtIndex:0]];
NSString *name_label = [NSString stringWithFormat:@"%@", [user_data[indexPath.row] objectAtIndex:1]];
// Calculate the contact text widths.
NSDictionary *attributes = @{NSFontAttributeName:[UIFont fontWithName:@"SFUIDisplay-Thin" size:20.0f]};
CGRect rect = [user_label boundingRectWithSize:CGSizeMake(MAXFLOAT, 60) options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];
CGRect rect_two = [name_label boundingRectWithSize:CGSizeMake(MAXFLOAT, 60) options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];
// Add the other cell objects width to
// the biggest calculated text width.
CGFloat row_width = 0;
if (rect.size.width > rect_two.size.width) {
row_width = (rect.size.width + 55);
}
else {
row_width = (rect_two.size.width + 55);
}
// Only return the generated width if
// it is bigger than the original width.
if (row_width > 106) {
return CGSizeMake(row_width, 60.f);
}
else {
return CGSizeMake(106, 60.f);
}
}