लेबल की चौड़ाई के आधार पर UICollectionView की गतिशील सेल चौड़ाई


94

मेरे पास एक 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;
}

इसी तरह की समस्या ... stackoverflow.com/questions/24915443/… ???
फेटी

जवाबों:


85

में sizeForItemAtIndexPathपाठ का आकार वापसी

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

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

4
आप कल्पना नहीं कर सकते कि मैं आपको कैसे धन्यवाद देता हूँ! यह वास्तव में काम करता है। अब मुझे केवल [cell.myLabel sizeToFit] समस्या को हल करने की आवश्यकता है, क्योंकि यह स्क्रॉलिंग के बाद ही अपने पूर्ण आकार में दिखाई देती है। लेकिन मैं आपके समाधान के करीब भी नहीं गया हूं।
लुगदी १

आपकी मदद के लिए धन्यवाद, लेकिन मेरे पास अभी भी एक मुद्दा है। जब मैं असहज करता हूं [cell.myLabel sizeToFit] मेरे पास नीचे की तरफ कटे हुए अक्षर और अक्षर हैं लेकिन मेरे स्क्रॉल करने के बाद यह ठीक हो जाता है (शब्द उनके सामान्य आकार के होते हैं और अक्षर थोड़ा ऊपर उछल जाते हैं)। यदि मैं टिप्पणी करता हूं और [cell.myLabel sizeToFit] संदेश को निष्क्रिय करता हूं (मैंने आईबी के साथ खेलने का फैसला किया और यह ठीक काम करता है) मेरे पास अंत और तल पर कटे हुए शब्द हैं। मैंने एक स्क्रीनशॉट बनाया goo.gl/HaoqQV यह गैर-रेटिना डिस्प्ले पर बहुत तेज नहीं है, लेकिन आप देख सकते हैं कि पत्रों ने काट दिया है। कैसे हल करने के लिए आपका सुझाव वास्तव में सराहना की जाएगी!
लुगदी

2
आकार के बजाय, टेक्स्ट के CGSize को पाने के लिए sizeWithAttributes का उपयोग करें, फिर नए आकार के साथ लेबल के फ्रेम को सेट करें।
बशीर_काड

सुझाव के लिए धन्यवाद, लेकिन मैं अभी भी नीचे और अंत में myLabel कटौती की है। हो सकता है कि मैं आपके सुझाव के कार्यान्वयन में गलत हूं। यहाँ मेरा कोड है
लुगदी

- (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; }
पल्प

49

स्विफ्ट 4.2+

सिद्धांत है:

  1. सुनिश्चित करें कि प्रतिनिधिमंडल स्थापित है (उदाहरण के लिए collectionView.delegate = self)

  2. कार्यान्वयन UICollectionViewDelegateFlowLayout(इसमें आवश्यक विधि हस्ताक्षर शामिल हैं)।

  3. कॉल collectionView...sizeForItemAtविधि।

  4. पुल-कास्ट करने के लिए कोई ज़रूरत नहीं Stringकरने के लिए NSStringकॉल करने के लिए size(withAttributes:विधि। स्विफ्ट Stringबॉक्स से बाहर है।

  5. विशेषताएँ वही हैं जो आप सेट करते हैं (NS)AttributedString, यानी फ़ॉन्ट परिवार, आकार, वजन, आदि। वैकल्पिक पैरामीटर।


नमूना समाधान:

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

लेकिन आप अपने सेल से संबंधित ठोस स्ट्रिंग विशेषताओं को निर्दिष्ट करना चाहेंगे, इसलिए अंतिम रिटर्न इस तरह दिखाई देगा:

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

आकार की गणना करने के लिए आप UILabel का उपयोग क्यों नहीं करेंगे? यहाँ सुझाया गया समाधान है:

let label = UILabel(frame: CGRect.zero)
label.text = textArray[indexPath.item]
label.sizeToFit()

हां, आपको वही परिणाम मिलता है। यह सरलीकृत लग रहा है और एक समाधान के रूप में लग सकता है। लेकिन यह अनुचित है क्योंकि: 1) यह महंगा है, 2) ओवरहेड और 3) गंदा है।

यह महंगा है क्योंकि यूआईबेल एक जटिल यूआई ऑब्जेक्ट है, जिसे हर पुनरावृत्ति पर बनाया जा रहा है, जब भी आपका सेल यहां दिखाने वाला है, भले ही आपको इसकी आवश्यकता न हो। यह एक ओवरहेड समाधान है क्योंकि आपको केवल एक पाठ का आकार प्राप्त करने की आवश्यकता है , लेकिन आप पूरे यूआई ऑब्जेक्ट बनाने के लिए जाते हैं। और यह उस कारण से गंदा है।


1
सेट करना न भूलेंcollectionView.delegate == self // or whatever-object-which-do-it
Fitsyu

बहुत बढ़िया जवाब। हालाँकि मुझे जो आकार मिल रहा था, वह जरूरत से थोड़ा छोटा था, अलग-अलग लंबाई के तार पर, मैंने आकार को थोड़ा संशोधित करने का फैसला किया। चौड़ाई में अतिरिक्त 5 अंक जोड़ने से चाल CGSize(width: title.size(withAttributes: [NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 16)]).width + 5, height: 50)
चली गई

37

मुझे स्विफ्ट 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)
        }

8
इसका उपयोग करने में सावधानी बरतें। प्रत्येक सेल गणना के लिए एक नया UILabel बनाना और आरेखण करना बहुत महंगा है।
एंथनी

जरूरत है UICollectionViewDelegateFlowLayout
cristianego

3
यह महंगा डमी लेबल बनाने के बारे में टिप्पणी को संबोधित करने के लिए, शायद आप कई के बजाय सिर्फ एक डमी लेबल बना सकते हैं। आप वास्तव में यह चाहते हैं कि लेबल विशेषताओं से पाठ का आकार हो। हालांकि दिन के अंत में, यह अनिवार्य रूप से पाठ आकार की गणना के रूप में ही है sizeWithAttributes, इसलिए शायद यह पसंदीदा उत्तर है।
स्टीफन पॉल

@ हसन धन्यवाद भाई यह मेरे लिए काम किया है, लेकिन मुझे चौड़ाई में एक समस्या मिली है इसलिए CGSize (चौड़ाई: label.frame. उपलब्धता + 50, ऊंचाई: 32) को जोड़ा। फिर यह काम किया, मुझे लगता है कि यह उत्तर शीर्ष सूची में होना चाहिए।
अरशद शेख

27

कोड से नीचे का चेकआउट आपको बहुत कम CGSize दे सकता है।

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

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

@ वीनेश टीपी आपकी प्रतिक्रिया के लिए धन्यवाद, मैं निश्चित रूप से इसकी जांच करूंगा और आपको बताऊंगा!
लुगदी

+1000 यह निश्चित रूप से काम करता है। आपकी और बशीर की पोस्ट पर एक साथ हरे रंग का चेक मार्क होना चाहिए।
चट्टानी रैकून

किसी भी विचार कैसे 3 स्विफ्ट के साथ ऐसा करने के लिए?
UKDataGeek

1
थैंक्स मैन, इट्स पार्टी टाइम !!
रवि



0

// डूडल देखने में जोड़ें

UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    [layout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
    layout.estimatedItemSize = CGSizeMake(self.breadScrumbCollectionView.frame.size.width, 30); 
self.breadScrumbCollectionView.collectionViewLayout = layout;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.