पैडिंग ए UILabel
, पूर्ण समाधान। 2020 के लिए अद्यतन किया गया।
यह पता चला है कि वहाँ तीन चीजें हैं जो किया जाना चाहिए।
1. नए छोटे आकार के साथ textRect # forBounds कॉल करना चाहिए
2. नए छोटे आकार के साथ drawText को ओवरराइड करना चाहिए
3. यदि एक गतिशील रूप से आकार की सेल, को आंतरिक रूप से समायोजित करना चाहिए
नीचे दिए गए विशिष्ट उदाहरण में, टेक्स्ट यूनिट एक टेबल व्यू, स्टैक व्यू या इसी तरह के निर्माण में है, जो इसे एक निश्चित चौड़ाई देता है । उदाहरण में हम 60,20,20,24 की पैडिंग चाहते हैं।
इस प्रकार, हम "मौजूदा" इंट्रेंसिक कॉन्टेंटसाइज लेते हैं और वास्तव में ऊंचाई में 80 जोड़ते हैं ।
दोहराना ...
आपको सचमुच इंजन द्वारा "अब तक की गणना की गई ऊंचाई" प्राप्त करना होगा, और उस मूल्य को बदलना होगा ।
मुझे लगता है कि प्रक्रिया भ्रामक है, लेकिन, यह है कि यह कैसे काम करता है। मेरे लिए, Apple को "प्रारंभिक ऊंचाई गणना" जैसी किसी चीज़ का नाम उजागर करना चाहिए।
दूसरी बात यह है कि हमें वास्तव में textRect # forBounds call का उपयोग अपने नए छोटे आकार के साथ करना है ।
तो textRect # forBounds में हम पहले आकार को छोटा बनाते हैं और फिर सुपर कहते हैं।
चेतावनी! आप चाहिए सुपर फोन के बाद , पहले नहीं!
यदि आप इस पृष्ठ पर सभी प्रयासों और चर्चा की सावधानीपूर्वक जांच करते हैं, तो यह सटीक समस्या है। ध्यान दें कि कुछ समाधान "लगभग काम करने लगते हैं" लेकिन फिर कोई व्यक्ति रिपोर्ट करेगा कि कुछ स्थितियों में यह काम नहीं करेगा। यह वास्तव में सटीक कारण है - भ्रामक रूप से आपको "सुपर बाद में कॉल करना चाहिए", इससे पहले नहीं।
इसलिए, यदि आप इसे "गलत क्रम में" सुपर कहते हैं, तो यह आमतौर पर काम करता है, लेकिन कुछ विशिष्ट पाठ लंबाई के लिए नहीं ।
यहां "गलत तरीके से सुपर पहले करने" का एक सटीक दृश्य उदाहरण है:
ध्यान दें कि 60,20,20,24 मार्जिन सही हैं लेकिन आकार की गणना वास्तव में गलत है, क्योंकि यह textRect # forBounds में "सुपर फर्स्ट" पैटर्न के साथ किया गया था।
फिक्स्ड:
ध्यान दें कि केवल अब textRect # forBounds इंजन जानता है कि गणना ठीक से कैसे करें :
आखिरकार!
फिर, इस उदाहरण में यूआईबेल का उपयोग उस विशिष्ट स्थिति में किया जा रहा है जहां चौड़ाई तय की गई है। अत: आंतरिकसंबंध में हमें अपनी इच्छित समग्र अतिरिक्त ऊंचाई को "जोड़ना" होगा। (आपको चौड़ाई में किसी भी तरह से "जोड़ने" की आवश्यकता नहीं है, यह तय होने के साथ ही व्यर्थ होगा।)
फिर TextRect # फोरबाउंड्स में आपको ऑटोलैयट द्वारा "अब तक सुझाई गई सीमा" मिलती है, आप अपने मार्जिन को घटाते हैं, और उसके बाद ही textRect # forBounds इंजन को फिर से कॉल करते हैं, जो कि सुपर में कहना है, जो आपको एक परिणाम देगा।
अंत में और बस ड्रा में आप निश्चित रूप से उसी छोटे बॉक्स में आकर्षित करते हैं।
ओह!
let UIEI = UIEdgeInsets(top: 60, left: 20, bottom: 20, right: 24) // as desired
override var intrinsicContentSize:CGSize {
numberOfLines = 0 // don't forget!
var s = super.intrinsicContentSize
s.height = s.height + UIEI.top + UIEI.bottom
s.width = s.width + UIEI.left + UIEI.right
return s
}
override func drawText(in rect:CGRect) {
let r = rect.inset(by: UIEI)
super.drawText(in: r)
}
override func textRect(forBounds bounds:CGRect,
limitedToNumberOfLines n:Int) -> CGRect {
let b = bounds
let tr = b.inset(by: UIEI)
let ctr = super.textRect(forBounds: tr, limitedToNumberOfLines: 0)
// that line of code MUST be LAST in this function, NOT first
return ctr
}
एक बार फिर। ध्यान दें कि इस और अन्य QA के उत्तर जो "लगभग" सही हैं ऊपर की पहली छवि में समस्या है - "सुपर गलत जगह पर है" । आपको इंट्रेंसिक कॉन्टेंटसाइज में बड़े आकार को मजबूर करना होगा और फिर टेक्स्ट # फॉर्बाउंड में आपको पहले-पहले की सीमा को छोटा करना होगा और फिर सुपर कॉल करना होगा।
सारांश: आपको textRect # forBounds में " सुपर लास्ट " कॉल करना होगा
यही रहस्य है।
ध्यान दें कि आपको आवश्यकता नहीं है और इसके अतिरिक्त अमान्य, sizeThatFits, needLayout या किसी अन्य मजबूर कॉल को कॉल करने की आवश्यकता नहीं है। एक सही समाधान सामान्य ऑटोलैयूट ड्रॉ चक्र में ठीक से काम करना चाहिए।
सुझाव:
यदि आप मोनोपेस फोंट के साथ काम कर रहे हैं, तो यहां एक शानदार टिप दी गई है: https://stackoverflow.com/a/59813420/46444