2009-09-18 9 views
22

मेरे ऐप में परिवर्तनीय ऊंचाई तालिका कक्ष होने की आवश्यकता है (जैसा कि प्रत्येक तालिका कक्ष ऊंचाई में भिन्न होता है, न कि प्रत्येक सेल को स्वयं का आकार बदलने में सक्षम होना चाहिए)।मैं आईफोन पर चरम ऊंचाई तालिका कक्ष कैसे कर सकता हूं?

मेरे पास एक समाधान है जो वर्तमान में काम करता है, लेकिन यह पतला और धीमा है।

मेरे वर्तमान समाधान:

से पहले तालिका सेल गाया जाता है, मैं गणना कैसे उच्च प्रत्येक कोशिका ऐसे -sizeWithFont:constrainedToSize: अपने डेटा पर के रूप में आकार तरीकों को फोन करके की जरूरत है। मैं फिर ऊंचाइयों को जोड़ता हूं, कुछ पैडिंग के लिए अनुमति देता हूं और परिणाम डेटा के साथ संग्रहीत करता हूं।

तब जब मेरे UITableViewDelegate को -tableview:heightForRowAtIndexPath: प्राप्त होता है तो मैं काम करता हूं कि उस सेल के लिए कौन सा आइटम प्रस्तुत किया जाएगा और उस ऊंचाई को वापस कर दें जिसे मैंने पहले गणना की थी।

जैसा कि मैंने कहा, यह काम करता है, लेकिन -sizeWithFont:constrainedToSize: पर कॉल करना बहुत धीमा है जब आप इसे सैकड़ों आइटम अनुक्रमिक रूप से कर रहे हैं, और मुझे लगता है कि यह बेहतर किया जा सकता है।

तो इसके लिए काम करने के लिए, मुझे कोड के दो हिस्सों को बनाए रखना था - एक जो सेल ऊंचाई की गणना करेगा, और वह समय जो आने पर कोशिकाओं को वास्तव में आकर्षित करेगा।

यदि मॉडल आइटम के बारे में कुछ भी बदल गया है, तो मुझे कोड के इन दोनों हिस्सों को अपडेट करना पड़ा था, और अब और फिर भी वे पूरी तरह से मेल नहीं खाते हैं, कभी-कभी परिणामस्वरूप टेबल कोशिकाएं जो किसी दिए गए के लिए बहुत छोटी होती हैं वस्तु, या बहुत बड़ी।

मेरे प्रस्तावित समाधान:

तो मैं सेल ऊंचाई precalculating को खत्म करना चाहते हैं। ए) क्योंकि यह एमवीसी प्रतिमान और बी तोड़ता है) क्योंकि यह धीमा है।

तो मेरा सेल स्वयं खींचता है, और नतीजतन, सही सेल ऊंचाई के साथ समाप्त होता है। मेरी समस्या यह है कि मेरे पास तालिका को खींचने से पहले सेल की ऊंचाई को देखने का कोई तरीका नहीं है - जिसके द्वारा बहुत देर हो चुकी है।

मैं -tableView:heightForRowAtIndexPath: के भीतर से -cellForRowAtIndexPath: बुला की कोशिश की लेकिन बाद पहली कुछ बिंदु पर दूसरा, और इसके विपरीत कॉल यह एक अनंत लूप में अटक जाता है, (कम से कम यह मैं क्या देखा है जब मैं इसे करने की कोशिश है)।

तो यह विकल्प प्रश्न से बाहर है।

यदि मैं पंक्ति प्रतिनिधि विधि के लिए ऊंचाई में एक आकार निर्दिष्ट नहीं करता हूं, तो तालिका दृश्य खराब हो जाता है। कोशिकाएं सही ऊंचाई हैं, लेकिन उनकी एक्स स्थिति निश्चित ऊंचाई की कोशिकाओं की है।

Messed Table Cells http://jamsoftonline.com/images/messed_table_cells.png

सूचना कैसे नीचे सेल सही आकार है - यह सिर्फ पिछले सेल अतिव्यापी है, और पिछले सेल अपने पिछले ओवरलैप करता है, और इतने पर और बहुत आगे है।

इस विधि का उपयोग करते हुए, स्क्रॉल करते समय कुछ आर्टिफैक्टिंग होती है जो मुझे लगता है कि कोशिकाओं के लिए पुन: उपयोग पहचानकर्ता से संबंधित हो सकता है।

तो यहां कोई भी सहायता की सराहना की जाएगी।

+0

मैं एक ही समस्या है। -cellForRowAtIndexPath: कॉल -tableView: heightForRowAtIndexPath: अगर बाद में कहा जाता है (ध्यान दें कि बाद वाले को कॉल नहीं किया जाता है तो बाद में कॉल नहीं किया जाता है) मुझे पागल बनाते हैं। – an0

उत्तर

38

यहां मैं उपयोग करता हूं। एनएसएसटींग में एक विधि है जो आपको फ़ॉन्ट जानकारी और ऊंचाई/चौड़ाई बाधाओं के आधार पर टेक्स्टबॉक्स के आयाम बताएगी।

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSString *text = [self getTextForIndexPath:indexPath]; 
    UIFont *font = [UIFont systemFontOfSize:14]; 
    CGSize size = [self getSizeOfText:text withFont:font]; 

    return (size.height + 11); // I put some padding on it. 
} 

तो फिर तुम लिखने के लिए एक विधि इस सेल के लिए पाठ खींच ...

- (NSString *)getTextForIndexPath:(NSIndexPath *)indexPath 
{ 
    NSString *sectionHeader = [self.tableSections objectAtIndex:[indexPath section]]; 
    NSString *sectionContent = [self.tableData objectForKey:sectionHeader]; 

    return sectionContent; 
} 

और इस पाठ का आकार पाने के लिए है।

- (CGSize)getSizeOfText:(NSString *)text withFont:(UIFont *)font 
{ 
    return [text sizeWithFont:font constrainedToSize:CGSizeMake(280, 500)]; 
} 
+0

किसने इसे कम किया और क्यों? – Jasarien

+1

मैं अपनी समूहीकृत तालिका में केवल एक सेल के लिए इस विधि का उपयोग कैसे कर सकता हूं? मैं सेल के अंदर एक पाठ दृश्य की ऊंचाई के आधार पर सेल की ऊंचाई वापस करना चाहता हूं ... – matteodv

+0

हाय। मैं जानना चाहता हूं कि 'self.tableSctions' और 'self.tableData' क्या है। मुझे पता है कि वे एनएसएआरएआरई और एनएस डिक्शनरी हैं, लेकिन क्या इसका मतलब यह है कि आपने इन वर्गों की सामग्री के लिए तालिका अनुभागों और एक शब्दकोश का एक सरणी बनाई है? मैं पूछ रहा हूं क्योंकि मैं केवल एक सेक्शन का उपयोग करता हूं और मैं इसे काम नहीं कर सकता। –

2

बस एक विचार:

  • क्या होगा यदि आप था, कहते हैं, कोशिकाओं के छह विभिन्न प्रकार के अपने स्वयं के पहचानकर्ता और एक निश्चित ऊंचाई के साथ प्रत्येक। एक एकल लाइन सेल के लिए होगा, दूसरा दो लाइन सेल, आदि के लिए होगा ...

  • हर बार जब आपका मॉडल बदलता है, उस पंक्ति के लिए ऊंचाई की गणना करें तो निकटतम सेल प्रकार ढूंढें जिसमें ऊंचाई निकटतम हो आपको क्या चाहिए उस सेलटाइप पहचानकर्ता को मॉडल के साथ सहेजें। आप मॉडल में उस सेल के लिए निश्चित पंक्ति ऊंचाई भी संग्रहीत कर सकते हैं ताकि आप उसे टेबलव्यू में वापस कर सकें: heightForRowAtIndexPath कॉल (मैं इसे सेल क्लास के अंदर गणना करने के लिए मजबूर करने पर भी लटका नहीं दूंगा - तकनीकी रूप से यह हिस्सा नहीं है सेल ड्राइंग कार्यक्षमता और टेबलब्यू का उपयोग करने के लिए कौन सा सेल प्रकार बनाने के लिए कुछ और उपयोग करता है)।

  • रनटाइम पर, जब उस पंक्ति के लिए एक सेल वापस करने के लिए कहा जाता है तो आपको सेलटाइप पहचानकर्ता के साथ एक सेल (या सेल कैश से प्राप्त) बनाना होता है, मान लोड करें और आप जाने के लिए अच्छे हैं।

तो सेल ऊंचाई गणना बहुत धीमी है, तो आप एक ही चाल tableview कैश करता खींच सकते हैं और केवल मांग पर यह करना है जब सेल देखने में आता है हो सकता है। किसी भी समय, आपको केवल कोशिकाओं को देखने के लिए ही करना होगा, और उसके बाद केवल एक ही सेल के लिए इसे किसी भी अंत में स्क्रॉल करना होगा।

+0

मैंने अतीत में इस विचार के साथ खिलवाड़ किया है और यह वही करने के लिए नहीं मिला जो मैं चाहता था। लेकिन शायद मैं फिर कोशिश कर सकता हूँ। – Jasarien

+0

यह गलत करने के लिए एक अच्छा और मजेदार तरीका –

0

मुझे पता है यह अनंत लूप तुम उल्लेख की वजह से आप के लिए काम नहीं करेगा, लेकिन मैं हालांकि इस वजह से एक छोटे से अक्षम हो सकते कोशिकाओं layoutSubViews विधि

बुला के साथ कुछ सफलता मिली है CellForRowAtIndexPath और layoutSubViews दोनों को एकाधिक कॉल, मुझे लगता है कि कोड क्लीनर है।

-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    MyCell *cell = (MyCell *)[self tableView:tableView cellForRowAtIndexPath:indexPath]; 

    [cell layoutSubviews]; 

    return CGRectGetHeight(cell.frame); 
} 

और लेआउट कोड में:

- (void)layoutSubviews 
{ 
    [super layoutSubviews]; 

    //First expand the label to a large height to so sizeToFit isn't constrained 
    [self.myArbitrarilyLengthLabel setFrame:CGRectMake(self.myArbitrarilyLengthLabel.frame.origin.x, 
              self.myArbitrarilyLengthLabel.frame.origin.y, 
              self.myArbitrarilyLengthLabel.frame.size.width, 
              1000)]; 


    //let sizeToFit do its magic 
    [self.myArbitrarilyLengthLabel sizeToFit]; 

    //resize the cell to encompass the newly expanded label 
    [self setFrame:CGRectMake(self.frame.origin.x, 
          self.frame.origin.y, 
          self.frame.size.width, 
           CGRectGetMaxY(self.myArbitrarilyLengthLabel.frame) + 10)]; 
} 
संबंधित मुद्दे