एक विशिष्ट फ़ॉन्ट और फ़ॉन्ट-आकार के पाठ स्ट्रिंग की चौड़ाई की गणना कैसे करें?


82

मेरे पास एक UILabel है जो कुछ वर्ण प्रदर्शित करता है। जैसे "x", "y" या "rpm"। मैं लेबल में पाठ की चौड़ाई की गणना कैसे कर सकता हूं (यह पूरे उपलब्ध स्थान को ues नहीं करता है)? यह स्वचालित लेआउटिंग के लिए है, जहां एक और दृश्य में एक बड़ा फ्रेम आयत होगा यदि उस UILabel के अंदर एक छोटा पाठ है। क्या एक UIFont और फ़ॉन्ट आकार निर्दिष्ट होने पर पाठ की उस चौड़ाई की गणना करने के तरीके हैं? कोई लाइन-ब्रेक भी नहीं है और सिर्फ एक ही लाइन है।


मुझे नहीं पता कि आप किसी भी फ़ॉन्ट प्रकार के साथ ऐसा कैसे करेंगे, हालांकि, यदि आप एक निश्चित चौड़ाई के फ़ॉन्ट का उपयोग कर रहे हैं, तो आप वर्णों की संख्या का उपयोग करके गणना कर सकते हैं। मैं पूरी तरह से सूत्र के बारे में निश्चित नहीं हूं।
19

जवाबों:


74

आप वास्तव sizeWithFont:में NSString UIKit परिवर्धन में विभिन्न तरीकों के माध्यम से कर सकते हैं । आपके मामले में सबसे सरल संस्करण पर्याप्त होना चाहिए (क्योंकि आपके पास मल्टी-लाइन लेबल नहीं हैं):

NSString *someString = @"Hello World";
UIFont *yourFont = // [UIFont ...]
CGSize stringBoundingBox = [someString sizeWithFont:yourFont];

इस विधि के कई रूप हैं, उदाहरण के लिए। कुछ विचार विराम मोड या अधिकतम आकार।


1
क्या यह UIFont नहीं होना चाहिए * yourFont = // [UIFont ...]; हालांकि?
PinkFloydRocks 14

11
"sizeWithFont:" को हटा दिया गया है। Wcochran द्वारा उत्तर को चिह्नित किया जाना चाहिए।
फेरन मेनलिंच

4
चूंकि आपके पास हरे रंग का चेकमार्क है, इसलिए आपको अपने उत्तर को आकार बदलने के लिए बदलना चाहिए।
ग्लेन हॉव्स

80

जब sizeWithFontसे पदावनत किया गया है, मैं सिर्फ स्विफ्ट 4 और का उपयोग करने के लिए अपने मूल उत्तर को अपडेट करने जा रहा हूं.size

//: Playground - noun: a place where people can play

import UIKit

if let font = UIFont(name: "Helvetica", size: 24) {
   let fontAttributes = [NSAttributedStringKey.font: font]
   let myText = "Your Text Here"
   let size = (myText as NSString).size(withAttributes: fontAttributes)
}

आकार अंक में "योर टेक्स्ट हियर" का ऑनस्क्रीन आकार होना चाहिए।


इस समाधान को पोस्ट करने के लिए धन्यवाद। मैंने आपके उत्तर के आधार पर विस्तार लिखा है। यह नीचे पोस्ट किया गया है।
एड्रियन

स्विफ्ट 4 में संबंधित फ़ंक्शन क्या होगा?
स्वयंभू

77

sizeWithFont:अब हटा दिया गया है, sizeWithAttributes:इसके बजाय उपयोग करें :

UIFont *font = [UIFont fontWithName:@"Helvetica" size:30];
NSDictionary *userAttributes = @{NSFontAttributeName: font,
                                 NSForegroundColorAttributeName: [UIColor blackColor]};
NSString *text = @"hello";
...
const CGSize textSize = [text sizeWithAttributes: userAttributes];

8
नोट: sizeWithAttributes:विधि आंशिक आकार देता है; विचारों को आकार देने के लिए लौटे आकार का उपयोग करने के लिए, आपको छत फ़ंक्शन का उपयोग करके इसके मूल्य को निकटतम उच्च पूर्णांक तक बढ़ाना होगा।
एलन

55

अद्यतन सितम्बर 2019

यह उत्तर नए सिंटैक्स का उपयोग करने के लिए एक बहुत क्लीनर तरीका है।

मूल उत्तर

ग्लेन होव्स के उत्कृष्ट उत्तर के आधार पर , मैंने एक स्ट्रिंग की चौड़ाई की गणना करने के लिए एक एक्सटेंशन बनाया। यदि आप किसी की चौड़ाई सेट करने जैसा कुछ कर रहे हैं UISegmentedControl, तो यह खंड के शीर्षक स्ट्रिंग के आधार पर चौड़ाई सेट कर सकता है।

extension String {

    func widthOfString(usingFont font: UIFont) -> CGFloat {
        let fontAttributes = [NSAttributedString.Key.font: font]
        let size = self.size(withAttributes: fontAttributes)
        return size.width
    }

    func heightOfString(usingFont font: UIFont) -> CGFloat {
        let fontAttributes = [NSAttributedString.Key.font: font]
        let size = self.size(withAttributes: fontAttributes)
        return size.height
    }

    func sizeOfString(usingFont font: UIFont) -> CGSize {
        let fontAttributes = [NSAttributedString.Key.font: font]
        return self.size(withAttributes: fontAttributes)
    }
}

उपयोग:

    // Set width of segmentedControl
    let starString = "⭐️"
    let starWidth = starString.widthOfString(usingFont: UIFont.systemFont(ofSize: 14)) + 16
    segmentedController.setWidth(starWidth, forSegmentAt: 3)

1
स्विफ्ट 4 के लिए क्या होगा समाधान?
स्वायम्भु

1
आकार (CGSize) लौटाने वाला केवल एक फ़ंक्शन क्यों नहीं? काम दो बार क्यों?
वाकोच्रान

@wcochran अपडेट किया गया। शानदार कॉल।
एड्रियन

1
मैं नहीं जानता कि कैसे, लेकिन यह मुझे गलत आकार देता है।
मैक्स

कोई बात नहीं, यह काम करता है लेकिन मेरे परीक्षणों से आपको पाठ को कम करने से रोकने के लिए कम से कम 15 की अतिरिक्त पैडिंग जोड़ने की आवश्यकता है ।
अधिकतम

33

स्विफ्ट-5

पाठ की ऊँचाई और चौड़ाई ज्ञात करने के लिए intrinsicContentSize का उपयोग करें।

yourLabel.intrinsicContentSize.width

यहां तक ​​कि यह आपके स्ट्रिंग के बीच "TEX T" जैसे कस्टम रिक्ति भी काम करेगा


28

स्विफ्ट 4.2 🔸 में ऑनलाइनर

let size = text.size(withAttributes:[.font: UIFont.systemFont(ofSize:18.0)])

6

स्विफ्ट में यह सरल विस्तार अच्छी तरह से काम करता है।

extension String {
    func size(OfFont font: UIFont) -> CGSize {
        return (self as NSString).size(attributes: [NSFontAttributeName: font])
    }
}

उपयोग:

let string = "hello world!"
let font = UIFont.systemFont(ofSize: 12)
let width = string.size(OfFont: font).width // size: {w: 98.912 h: 14.32}

3

स्विफ्ट 4

extension String {
    func SizeOf(_ font: UIFont) -> CGSize {
        return self.size(withAttributes: [NSAttributedStringKey.font: font])
    }
}

2

यह स्विफ्ट 2.3 वर्जन के लिए है। आप स्ट्रिंग की चौड़ाई प्राप्त कर सकते हैं।

var sizeOfString = CGSize()
if let font = UIFont(name: "Helvetica", size: 14.0)
    {
        let finalDate = "Your Text Here"
        let fontAttributes = [NSFontAttributeName: font] // it says name, but a UIFont works
        sizeOfString = (finalDate as NSString).sizeWithAttributes(fontAttributes)
    }

2

यदि आप मल्टीलाइन समर्थन के साथ पाठ की चौड़ाई प्राप्त करने के लिए संघर्ष कर रहे हैं , तो आप अगले कोड ( स्विफ्ट 5 ) का उपयोग कर सकते हैं :

func width(text: String, height: CGFloat) -> CGFloat {
    let attributes: [NSAttributedString.Key: Any] = [
        .font: UIFont.systemFont(ofSize: 17)
    ]
    let attributedText = NSAttributedString(string: text, attributes: attributes)
    let constraintBox = CGSize(width: .greatestFiniteMagnitude, height: height)
    let textWidth = attributedText.boundingRect(with: constraintBox, options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil).width.rounded(.up)

    return textWidth
}

और इसी तरह आप पाठ की ऊंचाई पा सकते हैं यदि आपको जरूरत है (बस कोस्ट्रेन्थबॉक्स कार्यान्वयन स्विच करें):

let constraintBox = CGSize(width: maxWidth, height: .greatestFiniteMagnitude)

या यहाँ बहुस्तरीय समर्थन के साथ पाठ का आकार प्राप्त करने के लिए एक एकीकृत कार्य है:

func labelSize(for text: String, maxWidth: CGFloat, maxHeight: CGFloat) -> CGSize {
    let attributes: [NSAttributedString.Key: Any] = [
        .font: UIFont.systemFont(ofSize: 17)
    ]

    let attributedText = NSAttributedString(string: text, attributes: attributes)

    let constraintBox = CGSize(width: maxWidth, height: maxHeight)
    let rect = attributedText.boundingRect(with: constraintBox, options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil).integral

    return rect.size
}

उपयोग:

let textSize = labelSize(for: "SomeText", maxWidth: contentView.bounds.width, maxHeight: .greatestFiniteMagnitude)
let textHeight = textSize.height.rounded(.up)
let textWidth = textSize.width.rounded(.up)

1

के लिए स्विफ्ट 3.0+

extension String {
    func SizeOf_String( font: UIFont) -> CGSize {
        let fontAttribute = [NSFontAttributeName: font]
        let size = self.size(attributes: fontAttribute)  // for Single Line
       return size;
   }
}

इसका इस्तेमाल ऐसे करें ...

        let Str = "ABCDEF"
        let Font =  UIFont.systemFontOfSize(19.0)
        let SizeOfString = Str.SizeOfString(font: Font!)

1

यह सुनिश्चित नहीं है कि यह कितना कुशल है, लेकिन मैंने इस फ़ंक्शन को लिखा है जो उस बिंदु आकार को लौटाता है जो एक स्ट्रिंग को दिए गए चौड़ाई में फिट होगा:

func fontSizeThatFits(targetWidth: CGFloat, maxFontSize: CGFloat, font: UIFont) -> CGFloat {
    var variableFont = font.withSize(maxFontSize)
    var currentWidth = self.size(withAttributes: [NSAttributedString.Key.font:variableFont]).width

    while currentWidth > targetWidth {
        variableFont = variableFont.withSize(variableFont.pointSize - 1)
        currentWidth = self.size(withAttributes: [NSAttributedString.Key.font:variableFont]).width
    }

    return variableFont.pointSize
}

और इसका उपयोग इस तरह किया जाएगा:

textView.font = textView.font!.withSize(textView.text!.fontSizeThatFits(targetWidth: view.frame.width, maxFontSize: 50, font: textView.font!))


0

जिस तरह से मैं इसे कर रहा हूं मेरा कोड UIFont का विस्तार करना है: (यह स्विफ्ट 4.1 है)

extension UIFont {


    public func textWidth(s: String) -> CGFloat
    {
        return s.size(withAttributes: [NSAttributedString.Key.font: self]).width
    }

} // extension UIFont
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.