Saya memiliki UICollectionView, yang memuat sel dari sel yang dapat digunakan kembali, yang berisi label. Sebuah array menyediakan konten untuk label itu. Saya dapat mengubah ukuran lebar label tergantung pada lebar konten dengan mudah dengan sizeToFit. Tapi saya tidak bisa membuat sel agar sesuai dengan label.
Ini kodenya
- (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;
}
Jawaban:
Sebagai
sizeForItemAtIndexPath
imbalannya ukuran teks- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{ return [(NSString*)[arrayOfStats objectAtIndex:indexPath.row] sizeWithAttributes:NULL]; }
sumber
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ Cell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"qw" forIndexPath:indexPath]; cell.myLbale.text = [NSString stringWithFormat:@"%@",[arrayOfStats objectAtIndex:indexPath.item]]; CGSize textSize; textSize = [[arrayOfStats objectAtIndex:indexPath.item] sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12.0f]}]; [cell.myLbale sizeThatFits:textSize]; //[cell.myLbale sizeToFit]; return cell; }
Swift 4.2+
Prinsipnya adalah:
Pastikan delegasi disiapkan (mis.
collectionView.delegate = self
)Implementasikan
UICollectionViewDelegateFlowLayout
(ini berisi tanda tangan metode yang diperlukan).collectionView...sizeForItemAt
Metode panggilan .Tidak perlu menjembatani metode cast
String
toNSString
to callsize(withAttributes:
. SwiftString
memilikinya di luar kotak.Atribut sama dengan yang Anda tetapkan
(NS)AttributedString
, yaitu jenis font, ukuran, berat, dll. Parameter opsional.Solusi sampel:
extension ViewController: UICollectionViewDelegateFlowLayout { func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return "String".size(withAttributes: nil) } }
Tetapi Anda kemungkinan besar ingin menentukan atribut string konkret masing-masing ke sel Anda, maka hasil akhir akan terlihat seperti:
extension ViewController: UICollectionViewDelegateFlowLayout { func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { // dataArary is the managing array for your UICollectionView. let item = dataArray[indexPath.row] let itemSize = item.size(withAttributes: [ NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 14) ]) return itemSize } }
Mengapa Anda TIDAK HARUS menggunakan UILabel untuk menghitung ukuran? Inilah solusi yang disarankan:
let label = UILabel(frame: CGRect.zero) label.text = textArray[indexPath.item] label.sizeToFit()
Ya, Anda mendapatkan hasil yang sama. Ini terlihat sederhana dan mungkin tampak sebagai solusi masuk ke. Tapi itu tidak tepat karena: 1) mahal, 2) overhead dan 3) kotor.
Biayanya mahal karena UILabel adalah objek UI yang kompleks, yang dibuat pada setiap iterasi setiap kali sel Anda akan ditampilkan meskipun Anda tidak membutuhkannya di sini. Ini adalah solusi overhead karena Anda hanya perlu mendapatkan ukuran teks, tetapi Anda melangkah lebih jauh untuk membuat objek UI secara keseluruhan. Dan itu kotor karena alasan itu.
sumber
collectionView.delegate == self // or whatever-object-which-do-it
CGSize(width: title.size(withAttributes: [NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 16)]).width + 5, height: 50)
Saya telah menemukan trik kecil untuk Swift 4.2
Untuk lebar dinamis & tinggi tetap:
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) }
Untuk tinggi dinamis & lebar tetap:
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) }
sumber
sizeWithAttributes
, jadi mungkin itu adalah jawaban yang lebih disukai.Lihat kode di bawah ini yang mungkin Anda berikan CGSize sangat singkat.
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{ NSString *testString = @"SOME TEXT"; return [testString sizeWithAttributes:NULL]; }
sumber
Di Swift 3
let size = (arrayOfStats[indexPath.row] as NSString).size(attributes: nil)
sumber
Cepat 4
let size = (arrayOfStats[indexPath.row] as NSString).size(withAttributes: nil)
sumber
// tambahkan tampilan didload
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; [layout setScrollDirection:UICollectionViewScrollDirectionHorizontal]; layout.estimatedItemSize = CGSizeMake(self.breadScrumbCollectionView.frame.size.width, 30); self.breadScrumbCollectionView.collectionViewLayout = layout;
sumber