ऑटोलाययूट - यूबूटन के आंतरिक आकार में शीर्षक इनसेट शामिल नहीं हैं


196

अगर मेरे पास ऑटोलाययूट का उपयोग करके यूआईबूटन की व्यवस्था है, तो इसकी सामग्री को फिट करने के लिए इसका आकार अच्छी तरह से समायोजित होता है।

यदि मैं एक छवि सेट करता हूं button.image, तो इंस्ट्रेंसिक आकार फिर से इसके लिए जिम्मेदार लगता है।

हालाँकि, अगर मैं titleEdgeInsetsबटन को मोड़ता हूँ, तो लेआउट इसके लिए जिम्मेदार नहीं है और इसके बजाय बटन शीर्षक को काटता है।

मैं यह कैसे सुनिश्चित कर सकता हूं कि इनसेट के लिए बटन की आंतरिक चौड़ाई?

यहां छवि विवरण दर्ज करें

संपादित करें:

मैं निम्नलिखित का उपयोग कर रहा हूं:

[self.backButton setTitleEdgeInsets:UIEdgeInsetsMake(0, 5, 0, 0)];

लक्ष्य छवि और पाठ के बीच कुछ अलगाव जोड़ना है।


3
क्या आपने इसे रडार के रूप में दर्ज किया था? यह निश्चित रूप से UIButton के आंतरिक आकार की गणना में एक बग प्रतीत होता है।
रयान पूलोस

1
मैं एक राडार दर्ज करने के लिए तैयार था, लेकिन यह वास्तव में एक अपेक्षित व्यवहार प्रतीत होता है। यह UIButton के * EdgeInsets गुणों पर प्रलेखित है : "आपके द्वारा निर्दिष्ट इनसेट को शीर्षक आयत पर लागू किया जाता है, उसके बाद बटन के पाठ को फिट करने के लिए आकार दिया गया है। इस प्रकार, सकारात्मक इनसेट मान वास्तव में शीर्षक पाठ को क्लिप कर सकते हैं। [...] बटन इस संपत्ति का उपयोग आंतरिक आंतरिक और आकार के आकार को निर्धारित करने के लिए नहीं करता है।
गुइलुम एलगिस

7
@GuillaumeAlgis मैं तर्क दूंगा कि हालांकि यह व्यवहार कहा गया है, यह बिल्कुल नहीं है कि ऑटोलैयूट का उपयोग करते समय क्या होने की उम्मीद है। मैंने एक बग दर्ज किया है और दूसरों को भी फाइल करने के लिए प्रोत्साहित करेगा।
मेमों

यदि आप यहां रडार बग से लिंक कर सकते हैं, तो क्या हम उस पर क्लिक कर सकते हैं और उस पर +1 कर सकते हैं?
गुरपसंत

1
से titleEdgeInsetप्रलेखन: The insets you specify are applied to the title rectangle after that rectangle has been sized to fit the button’s text. Thus, positive inset values may actually clip the title text. तो इनसेट जोड़कर आप बटन पक्का पाठ क्लिप करने के लिए मजबूर कर रहे हैं
मार्को Pappalardo

जवाबों:


192

आप किसी भी तरीके को ओवरराइड किए बिना या एक मनमाना चौड़ाई बाधा निर्धारित किए बिना इसे हल कर सकते हैं। आप इसे इंटरफ़ेस बिल्डर में निम्नानुसार कर सकते हैं।

  • आंतरिक बटन चौड़ाई शीर्षक चौड़ाई प्लस आइकन चौड़ाई प्लस छोड़ दिया और सही से ली गई है सामग्री बढ़त सन्निवेश वाली।

  • यदि किसी बटन में छवि और पाठ दोनों हैं, तो वे एक समूह के रूप में केंद्रित होते हैं, जिसके बीच कोई गद्दी नहीं होती है।

  • यदि आप एक बाईं सामग्री इनसेट जोड़ते हैं, तो यह पाठ के सापेक्ष गणना की जाती है, न कि टेक्स्ट + आइकन।

  • यदि आप एक नकारात्मक बाईं छवि इनसेट सेट करते हैं, तो छवि बाईं ओर खींची जाती है, लेकिन समग्र बटन चौड़ाई अप्रभावित है।

  • यदि आप एक नकारात्मक बाईं छवि इनसेट सेट करते हैं, तो वास्तविक लेआउट उस मूल्य का आधा उपयोग करता है। तो -20 पॉइंट वाले इनसेट को पाने के लिए, आपको इंटरफ़ेस बिल्डर में -40 पॉइंट लेफ्ट इनसेट वैल्यू का उपयोग करना होगा।

इसलिए आप आइकन और टेक्स्ट के बीच वांछित लेफ्ट इनसेट और इनर पैडिंग दोनों के लिए जगह बनाने के लिए एक बड़ा पर्याप्त कंटेंट इनसेट प्रदान करते हैं , और फिर आइकन और टेक्स्ट के बीच इच्छित पैडिंग की मात्रा को दोगुना करके बचे हुए आइकन को शिफ्ट करते हैं। परिणाम समान बाएँ और दाएँ सामग्री इनसेट और एक पाठ और आइकन जोड़ी के साथ एक बटन है जो एक समूह के रूप में केंद्रित होता है, जिसमें उनके बीच एक विशिष्ट राशि होती है।

कुछ उदाहरण मान:

// Produces a button with the layout:
// |-20-icon-10-text-20-|
// AutoLayout intrinsic width works as you'd desire.
button.contentEdgeInsets = UIEdgeInsetsMake(10, 30, 10, 20)
button.imageEdgeInsets = UIEdgeInsetsMake(0, -20, 0, 0)

क्यों वास्तविक लेआउट नकारात्मक बाईं इनसेट मान का आधा उपयोग करता है ?? मैंने उसी समस्या का सामना किया है!
टोनी लिन

1
यह बहुत अच्छी बात है कि वर्कअराउंड है, लेकिन मुझे आशा है कि इसका उपयोग अजीब व्यवहार को सही ठहराने के लिए नहीं किया गया है UIButton
फंक्शनल 7

205

आप इसे नकारात्मक और सकारात्मक शीर्षक और सामग्री इनसेट के संयोजन का उपयोग करके इंटरफ़ेस बिल्डर (किसी भी कोड को लिखे बिना) में काम करने के लिए प्राप्त कर सकते हैं।

यहां छवि विवरण दर्ज करें

अद्यतन : Xcode 7 में एक बग है जहां आप Rightइनसेट फ़ील्ड में नकारात्मक मान दर्ज नहीं कर सकते हैं , लेकिन आप मान को कम करने के लिए इसके बगल में स्टेपर नियंत्रण का उपयोग कर सकते हैं। (धन्यवाद स्टुअर्ट)

ऐसा करने से छवि और शीर्षक के बीच 8pt का अंतर आ जाएगा और एक ही राशि से बटन की आंतरिक चौड़ाई बढ़ जाएगी। ऐशे ही:

यहां छवि विवरण दर्ज करें


2
यह बटन चौड़ाई को बढ़ाने के लिए ऑटोलॉयआउट करने के लिए contentEdgeInsets (जो छोटी गाड़ी नहीं है) का उपयोग कर रहा है। और लेबल को दाईं ओर खाली जगह पर ले जाएं। शीर्षक किनारे इनसेट बग को हल करने का चतुर तरीका।
ugur

7
यह ट्रिक अब काम नहीं करती। इंटरफ़ेस बिल्डर अब Rightक्षेत्र में नकारात्मक मूल्यों को स्वीकार नहीं करता है ।
जॉरिस मैंस

7
@JorisMans आप नकारात्मक मान टाइप नहीं कर सकते हैं , लेकिन यह आवश्यक नकारात्मक मूल्य ... नीचे जाने के लिए पाठ फ़ील्ड के दाईं ओर स्टेपर नियंत्रण का उपयोग करके मेरे लिए काम किया ... आंकड़ा जाओ!
स्टुअर्ट

3
यह पहला उत्तर होना चाहिए, यह नीचे क्यों है? मैंने इसे खोजने से पहले अन्य 5 की कोशिश की है ...
लॉर्ड ज़सोल्ट

2
मैंने UIButton में पाठ को केन्द्रित करने के लिए सामग्री इनसेट 16 का अधिकार बनाया
coolcool1994

96

intrinsicContentSizeUIView पर विधि को ओवरराइड क्यों नहीं किया जाता है ? उदाहरण के लिए:

- (CGSize) intrinsicContentSize
{
    CGSize s = [super intrinsicContentSize];

    return CGSizeMake(s.width + self.titleEdgeInsets.left + self.titleEdgeInsets.right,
                      s.height + self.titleEdgeInsets.top + self.titleEdgeInsets.bottom);
}

यह ऑटोलैयूट प्रणाली को बताना चाहिए कि यह इनसेट्स की अनुमति देने के लिए बटन का आकार बढ़ाए और पूर्ण पाठ दिखाए। मैं अपने कंप्यूटर पर नहीं हूं, इसलिए मैंने यह परीक्षण नहीं किया है।


1
जहाँ तक मुझे पता है, बटन को ओवरराइड नहीं किया जाना चाहिए। समस्या यह है कि प्रत्येक बटन प्रकार एक अलग उपवर्ग द्वारा कार्यान्वित किया जाता है।
सुल्तान

2
intrinsicContentSizeUIView पर एक विधि है, UIButton नहीं है, इसलिए आप किसी भी UIButton विधियों में गड़बड़ नहीं करेंगे। Apple नहीं लगता है कि यह एक समस्या है: "इस पद्धति को ओवरराइड करने से कस्टम दृश्य को लेआउट सिस्टम से संवाद करने की अनुमति मिलती है कि वह अपनी सामग्री के आधार पर किस आकार का होना चाहता है।" और ओपी ने अलग-अलग बटन के बारे में कुछ नहीं कहा, सिर्फ एक।
मार्टन

1
यह निश्चित रूप से काम करता है और वह समाधान है जिसके साथ मैं गया था। intrinsicContentSizeवास्तव में UIView पर एक विधि है और UIButton UIView का एक उपवर्ग है, इसलिए निश्चित रूप से आप इस विधि को ओवरराइड कर सकते हैं; Apple के डॉक्स में कुछ भी नहीं कहा गया है कि आपको नहीं करना चाहिए। बस Maarten की ओवरराइड विधि का उपयोग करके एक UIButton उपवर्ग बनाएं और अपने UIButton को इंटरफ़ेस बिल्डर में बदलकर YourUIButtonSubclass टाइप करें और यह पूरी तरह से काम करेगा।
n8tr

37
intrinsicContentSizeUIButton के लिए मुझे लगता है शीर्षक में जोड़ना चाहिए, मैं Apple के साथ एक बग दर्ज करने जा रहा हूँ।
प्रोगामर

6
मैं सहमत हूँ, और imageEdgeInsets के लिए भी ऐसा ही है।
रिकार्डो सांचेज-साज़

87

आपने निर्दिष्ट नहीं किया है कि आप इनसेट्स को कैसे सेट कर रहे हैं, इसलिए मैं अनुमान लगा रहा हूं कि आप titleEdgeInsets का उपयोग कर रहे हैं क्योंकि मैं वही प्रभाव देख रहा हूं जो आप प्राप्त कर रहे हैं। अगर मैं इसके बजाय contentEdgeInsets का उपयोग करता हूं तो यह ठीक से काम करता है।

- (IBAction)ChangeTitle:(UIButton *)sender {
    self.button.contentEdgeInsets = UIEdgeInsetsMake(0,20,0,20);
    [self.button setTitle:@"Long Long Title" forState:UIControlStateNormal];
}

मैं वास्तव में titleEdgeInsets का उपयोग कर रहा हूं। मुझे छवि से शीर्षक को दूर करने की आवश्यकता है, न कि बटन के किनारे से छवि। शायद मैं बस कुछ गद्दी के साथ एक छवि का उपयोग करना चाहिए? हालांकि हैकी लगता है।
बेन पैकर्ड

यह ऑटोलैयूट के साथ संयोजन में पूरी तरह से काम करता है, धन्यवाद!
Cal S

3
यह बेहतर समाधान है, क्योंकि यह बिल्कुल वही करता है जो आप आंतरिक स्पर्श के बिना चाहते हैं।
RyJ

28
छवि का उपयोग करते समय और छवि और शीर्षक के बीच इनसेट को समायोजित करने की आवश्यकता होने पर यह प्रश्न का उत्तर नहीं देता है!
ब्रॉडी रॉबर्टसन

23

और स्विफ्ट के लिए यह काम किया:

extension UIButton {
    override open var intrinsicContentSize: CGSize {
        let intrinsicContentSize = super.intrinsicContentSize

        let adjustedWidth = intrinsicContentSize.width + titleEdgeInsets.left + titleEdgeInsets.right
        let adjustedHeight = intrinsicContentSize.height + titleEdgeInsets.top + titleEdgeInsets.bottom

        return CGSize(width: adjustedWidth, height: adjustedHeight)
    }
}

लव यू स्विफ्ट


1
भले ही आप ऐसा न करें, लेकिन इस मामले में उपवर्ग के लिए बेहतर है क्योंकि Apple डॉक्स स्पष्ट रूप से बताता है कि आंतरिक आकार में उसकी गणना में titEdgeInsets शामिल नहीं है और इसलिए एक एक्सटेंशन का उपयोग करके आप न केवल Apple की अपेक्षाओं का उल्लंघन कर रहे हैं - अन्य सभी डेवलपर्स जो पढ़ते हैं डॉक्स।
सायरन

18

यह धागा थोड़ा पुराना है, लेकिन मैं सिर्फ अपने आप में इस भाग गया और एक नकारात्मक इनसेट का उपयोग करके इसे हल करने में सक्षम था। उदाहरण के लिए, अपने इच्छित पैडिंग मानों को यहाँ प्रतिस्थापित करें:

UIButton* myButton = [[UIButton alloc] init];
// setup some autolayout constraints here
myButton.titleEdgeInsets = UIEdgeInsetsMake(-desiredBottomPadding,
                                            -desiredRightPadding,
                                            -desiredTopPadding,
                                            -desiredLeftPadding);

सही ऑटोलैयट बाधाओं के साथ संयुक्त, आप एक ऑटो-आकार वाले बटन के साथ समाप्त होते हैं जिसमें एक छवि और पाठ होता है! desiredLeftPadding10 सेट के साथ नीचे देखा ।

छवि और लघु पाठ के साथ बटन

छवि और लंबे पाठ के साथ बटन

आप देख सकते हैं कि बटन का वास्तविक फ्रेम लेबल को सम्मिलित नहीं करता है (चूंकि लेबल को 10 बिंदुओं को दाईं ओर स्थानांतरित कर दिया गया है, सीमा के बाहर), लेकिन हमने पाठ और चित्र के बीच पैडिंग के 10 अंक हासिल किए हैं।


1
यह वह समाधान है जिसका मैंने उपयोग किया है क्योंकि इसके लिए उपवर्ग की आवश्यकता नहीं है। काम नहीं करेगा अगर आपके बटन की पृष्ठभूमि है, लेकिन यह आमतौर पर iOS 7 के साथ कोई समस्या नहीं है
जोस मैनुअल सेंचेज

यह एक पृष्ठभूमि छवि के साथ काम करेगा यदि आप बटन की सामग्री ऑफसेट (सकारात्मक मूल्य> = शीर्षक इनसेट) सेट करते हैं।
बेन फ्लिन

9

Pegpeg के उत्तर के आधार पर स्विफ्ट 3 के लिए :

extension UIButton {

    override open var intrinsicContentSize: CGSize {

        let intrinsicContentSize = super.intrinsicContentSize

        let adjustedWidth = intrinsicContentSize.width + titleEdgeInsets.left + titleEdgeInsets.right
        let adjustedHeight = intrinsicContentSize.height + titleEdgeInsets.top + titleEdgeInsets.bottom

        return CGSize(width: adjustedWidth, height: adjustedHeight)

    }

}

हैलो। मैं इंटरफ़ेस बिल्डर में कस्टम एक्सटेंशन बटन का उपयोग करना चाहता हूं। plz मदद
केमदो

6

उपरोक्त सभी ने iOS 9+ के लिए काम नहीं किया , जो मैंने किया है:

  • एक चौड़ाई बाधा जोड़ें (न्यूनतम चौड़ाई के लिए जब बटन में कोई पाठ न हो। यदि पाठ प्रदान किया गया है तो बटन ऑटो पैमाने पर होगा)
  • ग्रेटर थान या इक्वल से संबंध स्थापित करना

यहां छवि विवरण दर्ज करें

अब बटन के चारों ओर एक सीमा जोड़ने के लिए बस विधि का उपयोग करें:

button.contentEdgeInsets = UIEdgeInsetsMake(0,20,0,20);

क्यों नहीं? यह स्वचालित रूप से सामग्री के साथ स्केल करता है, आपको बस एक न्यूनतम चौड़ाई निर्धारित करनी होगी (जो प्रदर्शित पाठ से छोटी हो सकती है)
Oritm

क्योंकि आप एक न्यूनतम चौड़ाई को परिभाषित करते हैं। ऑटोलैयट का पूरा विचार यह है कि यह किसी भी स्पष्ट (न्यूनतम) चौड़ाई को निर्धारित किए बिना किया गया है।
जॉरिस मैंस

इसकी चौड़ाई के बारे में नहीं, आप चाहें तो चौड़ाई को 1 पर सेट कर सकते हैं, लेकिन ऑटोलेयूट को यह जानना होगा कि चौड़ाई बराबर या अधिक हो सकती है । मैंने अपना जवाब अपडेट किया
Oritm

आपको चौड़ाई अवरोध की बिल्कुल भी आवश्यकता नहीं है, contentEdgeInset प्रमुख है, ऑटो लेआउट तब आंतरिक सामग्री आकार के लिए इसका उपयोग करता है।
क्रिस कॉनवर

5

मैं अपने UIButton आइकन और लेबल के बीच 5pt स्थान जोड़ना चाहता था। मैंने इसे कैसे हासिल किया:

UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeCustom];
// more button config etc
infoButton.contentEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 5);
infoButton.titleEdgeInsets = UIEdgeInsetsMake(0, 5, 0, -5);

जिस तरह से contentEdgeInsets, titleEdgeInsets और imageEdgeInsets एक-दूसरे से संबंधित हैं, उन्हें प्रत्येक इनसेट से थोड़ा सा लेने और लेने की आवश्यकता होती है। इसलिए यदि आप शीर्षक के बाईं ओर कुछ इनसेट जोड़ते हैं, तो आपको दाईं ओर ऋणात्मक इनसेट जोड़ना होगा और सामग्री को दाईं ओर कुछ और स्थान (सकारात्मक इनसेट के माध्यम से) प्रदान करना होगा।

शीर्षक की पारी से मेल खाने के लिए एक सही सामग्री इनसेट जोड़कर मेरा पाठ बटन की सीमा के बाहर नहीं जाता है।


3

इंटरफ़ेस बिल्डर में विकल्प भी उपलब्ध है। इनसेट देखिए। मैंने बाएं और दाएं सेट किया 3. एक आकर्षण की तरह काम करता है।

इंटरफ़ेस बिल्डर स्क्रीनशॉट


1
हाँ, जैसा कि यह उत्तर बताता है, इसका कारण यह है कि आप काम कर रहे हैं क्योंकि आप एज: कंटेंट को एज की बजाय यहाँ एडजस्ट कर रहे हैं : शीर्षक या एज: इमेज
स्माइबॉर्ग

1

मेरे द्वारा उपयोग किया जाने वाला समाधान बटन पर एक चौड़ाई की बाधा जोड़ना है। तब आपके पाठ के सेट हो जाने के बाद, आरंभीकरण में कहीं, चौड़ाई की कसौटी को अपडेट करें:

self.buttonWidthConstraint.constant = self.shareButton.intrinsicContentSize.width + 8;

जहां 8 जो भी आपका इनसेट है।


बटनविंडकॉन्स्ट्रैंट क्या है?
एलेक्सी गोलिकोव


1
यह एक महान समाधान नहीं है, क्योंकि यदि बटन की आंतरिक सामग्री का आकार बदलता है, तो आपको मैन्युअल रूप constantसे बाधा को नए मूल्य पर अपडेट करने की आवश्यकता होगी ... और यह जानना कि बटन के आंतरिक सामग्री आकार में परिवर्तन कब मुश्किल है? बटन को दबाए बिना।
स्माइबॉर्ग

Ayup। मैं अब इस विधि का उपयोग नहीं करता। आश्चर्यचकित था कि यह एक डाउन वोट के योग्य था, लेकिन ツ_ (_) _ /
it

setNeedsUpdateConstraintsबटन शीर्षक या छवि को अपडेट करने के बाद "मैन्युअल रूप से" कॉल किया जा सकता है। फिर आप ओवरराइड कर सकते हैं updateConstraintsऔर buttonWidthConstraintवहां से स्थिर गणना कर सकते हैं। यह जरूरी नहीं कि सबसे अच्छा तरीका हो लेकिन यह मेरे लिए काफी अच्छा है। YMMV;)
ओलिवियर

1

कॉलिंग sizeToFit () सुनिश्चित करता है कि contentEdgeInset को प्रभावी किया गया है

extension UIButton {

   open override func draw(_ rect: CGRect) { 
       self.contentEdgeInsets = UIEdgeInsets(top: 10, left: 40, bottom: 10, right: 40)
       self.sizeToFit()
   }
}

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