2013-08-19 11 views
26

मेरे पास है एक विधि है कि मुझे एक UITextView स्ट्रिंग की लंबाई को देखते हुए के लिए एकदम सही आकार (इसी सही फ़ॉन्ट आकार के साथ) देता है:मुझे बहिष्कृत आकार के साथ क्या करना चाहिए विथफॉन्ट: विधि?

- (NSInteger) heightOfLabel:(NSString*) string { 
    CGSize maximumLabelSize = CGSizeMake([[UIScreen mainScreen] bounds].size.width - 40, FLT_MAX); 
    CGSize expectedLabelSize = [[NSString stringTrimmedForLeadingAndTrailingWhiteSpacesFromString:string] 
      sizeWithFont:[UIFont systemFontOfSize:15] 
      constrainedToSize:maximumLabelSize 
      lineBreakMode:NSLineBreakByWordWrapping]; 

    return expectedLabelSize.height + 5; 
} 

वास्तव में, यह अभी भी मुझे एक सही फिट देता है, यहां तक ​​कि iOS7 में । हालांकि अब यह एक चेतावनी विधि के साथ आता है जो कहता है कि मुझे 'sizeWithFont: contrainedToSize: lineBreakMode' का उपयोग नहीं करना चाहिए।

अब इसे कहते हैं मैं -boundingRectWithSize का उपयोग करना चाहिए: विकल्प: विशेषताएं: संदर्भ:

इस विधि iOS7 के लिए नया नहीं है और इसलिए मैं समझ है कि यह ढेर अतिप्रवाह पर यह पूछने के लिए, बजाय जा रहा ठीक है आधिकारिक सेब डेवलपर्स मंच के लिए।

मैं तीन प्रश्न हैं:

1) क्योंकि यह अनुचित है, इसका मतलब यह है मैं निश्चित रूप से यह, के बावजूद यह अभी भी काम कर रहे बदलना चाहिए?

2) मैंने कई अलग-अलग बाउंडिंग RectWithSize की कोशिश की है: विधियों, विभिन्न चर के साथ, लेकिन यह कभी भी सही नहीं होता है, यह हमेशा थोड़ा सा लगता है (जैसा कि कई स्टैक ओवरफ्लो प्रश्न बताते हैं) - क्या इस के साथ कोई सही प्रतिस्थापन नहीं है विधि जो मेरी पिछली विधि के समान ही कम परेशानी के साथ समान है?

3) इस विधि को क्यों हटाएं? क्या यह इस अन्य विधि के साथ ओवरलैप की वजह से है?

+0

देखें इस [कड़ी] (http://www.cnblogs.com/lisa090818/p/3445161.html)। – yazh

+1

wtf वह लिंक है? – Rambatino

उत्तर

57

परीक्षण त्रुटि के एक घंटे मैं बनाने में कामयाब होने के बाद यह काम:

CGSize maximumLabelSize = CGSizeMake(tableView.width, MAXFLOAT); 

NSStringDrawingOptions options = NSStringDrawingTruncatesLastVisibleLine | 
           NSStringDrawingUsesLineFragmentOrigin; 

NSDictionary *attr = @{NSFontAttributeName: [UIFont systemFontOfSize:15]}; 
CGRect labelBounds = [string boundingRectWithSize:maximumLabelSize 
              options:options 
             attributes:attr 
              context:nil]; 

अद्यतन:

श्री टी नीचे जवाब में उल्लेख के रूप में: iOS 7 और बाद में में, यह विधि आंशिक आकार (लौटा सीजीआरईटी के आकार घटक में) लौटाती है; आकार के आकार में लौटा आकार का उपयोग करने के लिए, आपको छत समारोह का उपयोग करके निकटतम उच्च पूर्णांक में अपना मान बढ़ा देना चाहिए।ceilf फ़ंक्शन का उपयोग करने की अनुशंसा की जाती है।

CGFloat height = ceilf(labelBounds.size.height); 
+1

इसके लिए धन्यवाद। अब मैं आईओएस 6 के लिए कुछ समान उपयोग कर रहा हूं, जो स्ट्रिंग एट्रिब्यूट्स डिक्शनरी का उपयोग करके एनएसएट्रिब्रिटेड स्ट्रिंग बनाता है जो आप बनाते हैं और बाउंडिंग करते हैं RectWithSize: विकल्प: संदर्भ: जिम्मेदार स्ट्रिंग पर। – AidenMontgomery

+0

आप से भी ज्यादा! वास्तव में उपयोगी! – Andres

13

मेरा मानना ​​है कि क्योंकि NSString + UIKit कार्यों की उस श्रृंखला UIStringDrawing पुस्तकालय है, जो सुरक्षित थ्रेड नहीं किया गया था पर आधारित थे समारोह का बहिष्कार कर दिया गया था। यदि आपने उन्हें मुख्य थ्रेड (किसी अन्य UIKit कार्यक्षमता की तरह) पर चलाने की कोशिश की है, तो आपको अप्रत्याशित व्यवहार मिलेंगे। विशेष रूप से, यदि आप एक साथ कई धागे पर फ़ंक्शन चलाते हैं, तो यह शायद आपके ऐप को क्रैश कर देगा। यही कारण है कि आईओएस 6 में, उन्होंने NSAttributedStrings के लिए boundingRectWithSize:... विधि पेश की। यह NSStringDrawing पुस्तकालयों के शीर्ष पर बनाया गया था और धागा सुरक्षित है।

यदि आप नए एनएसएसटींग boundingRectWithSize:... फ़ंक्शन को देखते हैं, तो यह एनएसएट्रिब्यूटस्ट्रिंग के समान तरीके से एक विशेषता सरणी के लिए पूछता है। अगर मुझे लगता है कि आईओएस 7 में यह नया एनएसएसटींग फ़ंक्शन आईओएस 6 से एनएसएट्रिब्रिटीस्ट्रिंग फ़ंक्शन के लिए केवल एक रैपर है।

उस नोट पर, यदि आप केवल आईओएस 6 और आईओएस 7 का समर्थन कर रहे थे, तो मैं निश्चित रूप से सभी को बदल दूंगा NSSttributeString के boundingRectWithSize पर आपके NSString के sizeWithFont:... का। यदि आपके पास अजीब बहु-थ्रेडिंग कोने का मामला है तो यह आपको बहुत सी सिरदर्द बचाएगा!

क्या हुआ करता था:

NSString *text = ...; 
CGFloat width = ...; 
UIFont *font = ...; 
CGSize size = [text sizeWithFont:font 
       constrainedToSize:CGSizeMake(width, CGFLOAT_MAX)]; 

साथ प्रतिस्थापित किया जा सकता है:

NSString *text = ...; 
CGFloat width = ...; 
UIFont *font = ...; 
NSAttributedString *attributedText = 
    [[NSAttributedString alloc] 
     initWithString:text 
     attributes:@ 
     { 
      NSFontAttributeName: font 
     }]; 
CGRect rect = [attributedText boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX) 
              options:NSStringDrawingUsesLineFragmentOrigin 
              context:nil]; 
CGSize size = rect.size; 

कृपया प्रलेखन ध्यान दें का उल्लेख है:

आईओएस 7 में यहाँ कैसे मैं परिवर्तित NSString के sizeWithFont:constrainedToSize: है और बाद में, यह विधि आंशिक आकार लौटाती है (लौटाए गए सीजीआरईटी के आकार घटक में); लौटा आकार का आकार विचारों का उपयोग करने के लिए, आपको छत समारोह का उपयोग करके निकटतम उच्च पूर्णांक पर अपना मान बढ़ाने का उपयोग करना होगा।

तो गणना ऊंचाई या चौड़ाई विचारों को आकार देने के लिए इस्तेमाल किया जाएगा बाहर निकलने के लिए, मैं का प्रयोग करेंगे:

CGFloat height = ceilf(size.height); 
CGFloat width = ceilf(size.width); 
+4

लाइनब्रेकोड समस्या को संबोधित नहीं करता – Firdous

+0

नीचे मेरा उत्तर देखें। –

5

LINEBREAK मुद्दे के लिए:

- (CGFloat)heightNeededForText:(NSString *)text withFont:(UIFont *)font width:(CGFloat)width lineBreakMode:(NSLineBreakMode)lineBreakMode { 
    NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init]; 
     paragraphStyle.lineBreakMode = lineBreakMode; 
    CGSize size = [text boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX) 
            options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading) 
            attributes:@{ NSFontAttributeName: font, NSParagraphStyleAttributeName: paragraphStyle } 
            context:nil].size; 

    return ceilf(size.height); 
} 
2

की स्विफ्ट संस्करण नॉर्वे के उत्तर के अलेक्जेंडर ...

func heightNeededForText(text: NSString, withFont font: UIFont, width: CGFloat, lineBreakMode:NSLineBreakMode) -> CGFloat { 
     let paragraphStyle = NSMutableParagraphStyle() 
     paragraphStyle.lineBreakMode = lineBreakMode 
     let size: CGSize = text.boundingRectWithSize(CGSizeMake(width, CGFloat.max), options: [.UsesLineFragmentOrigin, .UsesFontLeading], attributes: [ NSFontAttributeName: font, NSParagraphStyleAttributeName: paragraphStyle], context: nil).size//text boundingRectWithSize:CGSizeMake(width, CGFLOAT_MA 

     return ceil(size.height); 
    } 

कोड जहां ऊंचाई सिर्फ फोन नीचे की तरह विधि प्राप्त करना चाहते हैं में ...

let size = self.heightNeededForText(text as NSString, withFont: UIFont.systemFontOfSize(15.0), width: scrollView.frame.size.width - 20, lineBreakMode: NSLineBreakMode.ByWordWrapping) //Can edit the font size and LinebreakMode 
संबंधित मुद्दे