Отрегулируйте ширину ячейки на основе текста - UICollectionView - iOS

У меня есть приложение для iOS с UICollectionView который представляет клетки по горизонтали. В каждой из ячеек я добавил одну простую метку (пока). Эти метки показывают имена, иногда имена короткие, и это нормально... но.... иногда имена длинные и поэтому обрезаются, потому что они не могут должным образом вписаться в ширину ячейки представления коллекции.

Есть ли способ динамически регулировать ширину ячейки / метки, чтобы текст имени отображался правильно?

Я экспериментировал, используя этот метод:

-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    return CGSizeMake(106.f, 60.f);
}

Но у меня есть две основные проблемы с вышеупомянутым методом:

  1. Как получить доступ к метке ячейки из этого метода? (Чтобы я мог получить его высоту).
  2. Как на самом деле выяснить, какой должна быть ширина ячейки / метки?

Спасибо за ваше время,

Дэн

4 ответа

Решение

Спасибо всем за публикацию, в конце концов, решение, которое работало для меня, было сочетанием всех ваших решений и небольшого количества дополнительных действий:

-(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);
    }
}

Вы не можете получить доступ к метке, но вы можете получить доступ к данным, которые вы используете для ее заполнения. С этим вы можете получить высоту и ширину вашего ярлыка:

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);
    }

Надеюсь, это поможет вам.

Другие вопросы по тегам