web-dev-qa-db-ja.com

ラベル幅に応じた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;
}
75
pulp

sizeForItemAtIndexPathには、テキストのサイズを返します

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

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

非常に短いCGSizeを提供している可能性があるコードの下のチェックアウト。

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

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

Swift 4.2 +

原則は次のとおりです。

  1. UICollectionViewDelegateFlowLayoutを実装します(必要なメソッドシグネチャが含まれます)

  2. collectionView...sizeForItemAtメソッドを呼び出します。

  3. size(withAttributes:メソッドを呼び出すためにStringNSStringにブリッジキャストする必要はありません。 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)
])
22
Hexfire

Swift 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)
        }
19
Hassan Izhar

Swift 3

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

Swift 4

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