Подтвердить что ты не робот

Ширина динамической ячейки UICollectionView в зависимости от ширины метки

У меня есть UICollectionView, который загружает ячейки из многоразовой ячейки, содержащей ярлык. Массив предоставляет контент для этой метки. Я могу изменить ширину метки в зависимости от ширины содержимого с помощью параметра sizeToFit. Но я не могу сделать ячейку подходящей меткой.

Здесь код

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    arrayOfStats =  @[@"time:",@"2",@"items:",@"10",@"difficulty:",@"hard",@"category:",@"main"];
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:     (NSInteger)section{
    return [arrayOfStats count];
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{

    return CGSizeMake(??????????);
}

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{

    return 1;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{

    Cell *cell = (Cell *) [collectionView dequeueReusableCellWithReuseIdentifier:@"qw" forIndexPath:indexPath];
    cell.myLabel.text = [NSString stringWithFormat:@"%@",[arrayOfStats objectAtIndex:indexPath.item]];
    // make label width depend on text width
    [cell.myLabel sizeToFit];

    //get the width and height of the label (CGSize contains two parameters: width and height)
    CGSize labelSize = cell.myLbale.frame.size;

    NSLog(@"\n width  = %f height = %f", labelSize.width,labelSize.height);

    return cell;
}
4b9b3361

Ответ 1

В sizeForItemAtIndexPath вернуть размер текста

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{

    return [(NSString*)[arrayOfStats objectAtIndex:indexPath.row] sizeWithAttributes:NULL];
}

Ответ 2

Оформить заказ ниже код, который вы могли бы дать очень короткий CGSize.

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{

    NSString *testString = @"SOME TEXT";
    return [testString sizeWithAttributes:NULL];
}

Ответ 3

В Swift 3

let size = (arrayOfStats[indexPath.row] as NSString).size(attributes: nil)

Ответ 4

Swift 4

let size = (arrayOfStats[indexPath.row] as NSString).size(withAttributes: nil)

Ответ 5

Свифт 4. 2+

Принцип таков:

  1. UICollectionViewDelegateFlowLayout (он содержит необходимую сигнатуру метода)

  2. Вызовите метод collectionView...sizeForItemAt.

  3. Нет необходимости NSString String с NSString для вызова size(withAttributes: метод. Swift String имеет его из коробки).

  4. Атрибуты те же, что и для (NS)AttributedString, то есть семейство шрифтов, размер, вес и т.д. Необязательный параметр.


Пример решения:

extension ViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return "String".size(withAttributes: nil)
    }
}

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

// Replace "String" with proper string (typically array element). 
return "String".size(withAttributes: [
    NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 14)
])

Ответ 6

Я нашел маленький трюк для быстрой 4.2

Для динамической ширины и фиксированной высоты:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let label = UILabel(frame: CGRect.zero)
        label.text = textArray[indexPath.item]
        label.sizeToFit()
        return CGSize(width: label.frame.width, height: 32)
    }

Для динамической высоты и фиксированной ширины:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
            let label = UILabel(frame: CGRect.zero)
            label.text = textArray[indexPath.item]
            label.sizeToFit()
            return CGSize(width: 120, height: label.frame.height)
        }

Ответ 7

//добавить в вид didload

UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    [layout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
    layout.estimatedItemSize = CGSizeMake(self.breadScrumbCollectionView.frame.size.width, 30); 
self.breadScrumbCollectionView.collectionViewLayout = layout;