iOS: UIButton टेक्स्ट की लंबाई के अनुसार आकार बदलता है


134

इंटरफ़ेस बिल्डर में, होल्डिंग Command+ =अपने पाठ को फिट करने के लिए एक बटन का आकार बदल देगा। मैं सोच रहा था कि बटन को दृश्य में जोड़ने से पहले यह प्रोग्रामेटिक रूप से करना संभव था या नहीं।

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button.titleLabel setFont:[UIFont fontWithName:@"Arial-BoldMT" size:12]];
[button addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
// I need to know the width needed to accomodate NSStringVariable
[button setTitle:NSStringVariable forState:UIControlStateNormal]; 
// So that I can set the width property of the button before addSubview
[button setFrame:CGRectMake(10, 0, width, fixedHeight)];
[subNavigation addSubview:button];

1
इस बहुत पुराने प्रश्न पर ध्यान दें: आजकल (2017), बस बाधा को "अधिक से अधिक या बराबर" के रूप में सेट करें और यह सब करता है। (टैड द्वारा नीचे दिए गए नोटिस का जवाब।)
फेटी

@ फैटी ए " अधिक से अधिक या बराबर " बाधा AutoLayout के साथ संगतता के लिए पर्याप्त नहीं है । आजकल (2017+) को या तो बटन को किसी चीज़ के अंदर लपेटना चाहिए जो ठीक से आकार देता हो (Bartłomiej Semańczyk उत्तर), या किसी को UIButton को उप-वर्ग में रखना चाहिए, जैसा कि stackoverflow.com/a/5057578833581
Cœur

hi @ C tour - ऑटोलैयूट के लिए कई सूक्ष्मताएँ हैं। यह संभव है कि आप थोड़ी अलग स्थिति के बारे में सोच रहे हों? हालाँकि, सौभाग्य से, आप पूरी तरह से गलत हैं - बस कोशिश करो !! बस एक यूआईयूटन को व्यू कंट्रोलर पर रखें। स्पष्ट रूप से क्षैतिज और ऊर्ध्वाधर केंद्र निर्धारित करें। और फिर एक> = 100 चौड़ाई की बाधा जोड़ें। यह नवीनतम iOS में पूरी तरह से काम करता है।
Fattie

1
(यहां किसी भी व्यक्ति के लिए ऑटोलैयूट गोलगप्पे के लिए नया ………। सिर्फ TBC आपको कुछ भी जोड़ना नहीं है, और UIButton (UILabel, आदि भी) पाठ परिवर्तनों के साथ स्वचालित रूप से चौड़ाई का आकार बदल देगा। ठीक से एच / वी स्थिति ठीक है।)
फेटी

@ फैटी प्रदर्शन । विशेष रूप से, रनटाइम में, यह इस तरह से व्यवहार करता है: github.com/Coeur/autolayoutButton/blob/master/buttonSelfSizing/…
Cœur

जवाबों:


1

Xcode 4.5 और इसके बाद के संस्करण में, यह अब ' ऑटो-लेआउटिंग / बाधाओं ' का उपयोग करके किया जा सकता है ।

प्रमुख लाभ यह हैं कि:

  1. आपको प्रोग्रामेटिक रूप से फ़्रेम सेट करने की आवश्यकता नहीं है!
  2. यदि सही किया जाता है, तो आपको ओरिएंटेशन परिवर्तनों के लिए फ़्रेम रीसेट करने के लिए परेशान होने की आवश्यकता नहीं है।
  3. इसके अलावा, डिवाइस परिवर्तन आपको परेशान नहीं करते हैं (पढ़ें, अलग-अलग स्क्रीन आकारों के लिए अलग से कोड की आवश्यकता नहीं है)।

कुछ नुकसान:

  1. नहीं पिछड़े संगत - केवल iOS 6 और इसके बाद के संस्करण के लिए काम करता है।
  2. परिचित होने की आवश्यकता है (लेकिन बाद में समय की बचत होगी)।

सबसे अच्छी बात यह है कि हम एक इरादे की घोषणा करने पर ध्यान केंद्रित करते हैं जैसे:

  • मैं चाहता हूं कि ये दोनों बटन एक ही चौड़ाई के हों; या
  • मुझे इस दृश्य को लंबवत केंद्रित करने और सुपरवाइवे के किनारे से अधिकतम 10 पीटी का विस्तार करने की आवश्यकता है; या और भी,
  • मैं इस बटन / लेबल को उस लेबल के अनुसार आकार बदलना चाहता हूं जो यह प्रदर्शित कर रहा है!

यहां ऑटो-लेआउटिंग से परिचित होने के लिए एक सरल ट्यूटोरियल है।

एक के लिए और अधिक जानकारी के

यह पहली बार में कुछ समय लेता है, लेकिन यह सुनिश्चित करता है कि यह प्रयास के लायक होगा।


3
मैं लगभग इस जवाब से चूक गया - यह वास्तव में बहुत अधिक वोटों की आवश्यकता है। इस समाधान के साथ एक फ़ॉन्ट फोंटनाम और आकार या iOS 7-केवल कॉल्स एम्बेड करने से बच सकते हैं। मैं बस उस साइड का अवरोध निर्धारित करता हूं जो मैं चाहता था कि मेरा यूब्यूट्टन आगे बढ़े और यही है।
कार्ल

लगभग एक सही समाधान, दुर्भाग्य से यह काम नहीं करता है यदि आप टाइटल का उपयोग करते हैं IInsets: /
Zoltán

130
यह एक खराब उत्तर है - यह ऑटोलेयआउट की खूबियों का ब्योरा देता है, बजाय इसके कि ऑटोचालक को इस स्थिति में आवेदनकर्ता की समस्या को हल करने के लिए कैसे लागू किया जा सकता है।
Mattsven

4
मैं सोच रहा था कि क्या यह संभव हो सकता है प्रोग्रामेटिक रूप से उत्तर कहता है ...
जुआन बोइरो

@JuanPabloBoeroAlvarez ऑटो लेआउट बाधाओं को इंटरफ़ेस बिल्डर और / या प्रोग्रामेटिक रूप से निर्दिष्ट किया जा सकता है।
स्लिप डी। थॉम्पसन

130

UIKit में, NSString वर्ग में कुछ दिए गए NSString ऑब्जेक्ट से प्राप्त करने के लिए कुछ निश्चित फॉन्ट में दिए गए आकार को जोड़ना होगा।

डॉक्स यहाँ था । अब यह यहाँ पदावनत है।

संक्षेप में, यदि आप जाते हैं:

CGSize stringsize = [myString sizeWithFont:[UIFont systemFontOfSize:14]]; 
//or whatever font you're using
[button setFrame:CGRectMake(10,0,stringsize.width, stringsize.height)];

... आपने बटन के फ्रेम को उस स्ट्रिंग की ऊँचाई और चौड़ाई पर सेट कर दिया है, जिसे आप प्रस्तुत कर रहे हैं।

आप शायद उस CGSize के आसपास कुछ बफर स्थान के साथ प्रयोग करना चाहते हैं, लेकिन आप सही जगह पर शुरू करेंगे।


4
ऐसा लगता है कि iOS डिफ़ॉल्ट पैडिंग 12px, 8px है।
बेन लछमन

19
sizeWithFont को iOS 7.0 में अपग्रेड किया गया है।
SizeWithAttributes का

6
मैं दृढ़ता से तख्ते के साथ नहीं खेलने का सुझाव देता हूं, लेकिन इसके बजाय केवल बाधाओं के साथ।
गिल सैंड

@ गिल्सैंड क्या इसके लिए इंटरफेस बिल्डर का उपयोग करने का एक तरीका है?
ह्यूगी जूल

हां, एक Google खोज आपको बहुत उपयोगी परिणाम प्रदान करना चाहिए
गिल सैंड

101

कोड में ऐसा करने का तरीका है:

[button sizeToFit];

यदि आप उपवर्ग कर रहे हैं और अतिरिक्त नियम जोड़ना चाहते हैं, तो आप ओवरराइड कर सकते हैं:

- (CGSize)sizeThatFits:(CGSize)size;

5
sizeToFit UIButton या UILabel जैसे मानक नियंत्रणों पर पूरी तरह से काम करता है। यदि आप इसे कस्टम UIView पर कर रहे हैं तो आपको इसे लागू करने की आवश्यकता होगी -(CGSize)sizeThatFits:(CGSize)size
कैमरन लोवेल पामर

4
यह केवल तभी काम करता है जब आप इसे टेक्स्ट सेट करने के बाद डालते हैं, अन्यथा इसके बारे में पर्याप्त जानकारी नहीं है कि यह कितना बड़ा होना चाहिए: [button setTitle:@"Your text here" forState:UIControlStateNormal]; [button sizeToFit]; इसके अलावा यदि आप टेक्स्ट को बाद में अपडेट करते हैं, तो फिर से कॉल करना न भूलें।
जुआन बोइरो

सुनिश्चित करें कि आपने केवल उसी तरह से टेक्स्ट सेट किया है: [myButton setTitle: @ "my title" forState: UIControlStateNormal]; मेरे लिए यह तब तक काम नहीं आया जब तक मैंने उस बयान को दोहराया नहीं।
डेरियस मिलियास्कस

7
sizeToFit()टाइटल एज इनसेट का सम्मान नहीं करता है।
केलिन

32

यदि आपका बटन इंटरफ़ेस बिल्डर के साथ बनाया गया था, और आप शीर्षक को कोड में बदल रहे हैं, तो आप यह कर सकते हैं:

[self.button setTitle:@"Button Title" forState:UIControlStateNormal];
[self.button sizeToFit];

1
और आप उस पर भी कर सकते हैं, भले ही आपका बटन कोड के साथ बनाया गया हो।
मार्कस

22

स्विफ्ट:

यहां महत्वपूर्ण बात यह है कि आप कब कॉल करेंगे .sizeToFit(), यह पाठ को प्रदर्शित करने के लिए सेट करने के बाद होना चाहिए ताकि यह आवश्यक आकार पढ़ सके, यदि आप बाद में पाठ को अपडेट करते हैं, तो इसे फिर से कॉल करें।

var button = UIButton()
button.setTitle("Length of this text determines size", forState: UIControlState.Normal)
button.sizeToFit()
self.view.addSubview(button)

18

ऑटोलेयूट का उपयोग करके इसे पूरा करने के लिए, एक चर चौड़ाई की सीमा निर्धारित करने का प्रयास करें:

चौड़ाई बाधा

आपको अपनी आवश्यकताओं को समायोजित करने Content Hugging Priorityऔर Content Compression Resistance Priorityपरिणामों को प्राप्त करने की आवश्यकता हो सकती है।


UILabel पूरी तरह से स्वचालित रूप से स्व-आकार देने है :

यह उइबेल बस स्क्रीन पर केंद्रित होने के लिए सेट है (केवल दो बाधाएं, क्षैतिज / ऊर्ध्वाधर):

यह पूरी तरह से स्वचालित रूप से चौड़ाई बदलता है:

आपको किसी भी चौड़ाई या ऊंचाई को निर्धारित करने की आवश्यकता नहीं है - यह पूरी तरह से स्वचालित है।

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

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

ध्यान दें कि छोटे पीले वर्ग बस संलग्न हैं (शून्य के "रिक्ति")। UILabel के आकार बदलने के बाद वे स्वचालित रूप से चले जाते हैं।

"> =" बाधा जोड़ना, यूआईबेल के लिए न्यूनतम चौड़ाई निर्धारित करता है:

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


16

यदि आप बटन के विपरीत पाठ का आकार बदलना चाहते हैं, तो आप उपयोग कर सकते हैं ...

button.titleLabel.adjustsFontSizeToFitWidth = YES;
button.titleLabel.minimumScaleFactor = .5;
// The .5 value means that I will let it go down to half the original font size 
// before the texts gets truncated

// note, if using anything pre ios6, you would use I think
button.titleLabel.minimumFontSize = 8;

3
* एडजस्टमेंटसाइज़टाइफ़िटविट्ठ
डेनियल बैंग

8

sizeToFit सही तरीके से काम नहीं करता है। बजाय:

myButton.size = myButton.sizeThatFits(CGSize.zero)

आप contentInsetबटन को भी जोड़ सकते हैं :

myButton.contentEdgeInsets = UIEdgeInsetsMake(8, 8, 4, 8)


Apple डॉक्स से sizeToFit के बारे में: // कॉल sizeThatFits: वर्तमान दृश्य सीमा के साथ और सीमा आकार बदलता है। तो यह सही ढंग से काम करता है आपको बस इसे सेट करना होगा उसके बाद आप पाठ सेट करें।
मार्कस

5

सीधे शब्दों में:

  1. UIViewचारों ओर देखने के लिए ऑटो लेआउट के साथ आवरण के रूप में बनाएं ।
  2. UILabelउस रैपर के अंदर रखो । बाधाओं को जोड़ें जो रैपर के किनारों पर टाइयर लेबल चिपका देगा।
  3. UIButtonअपने रैपर के अंदर रखें , फिर साधारण समान बाधाओं को जोड़ें जैसा आपने किया था UILabel
  4. टेक्स्ट के साथ अपने ऑटोसाइज्ड बटन का आनंद लें।

1
क्या यह सुगमता के साथ अच्छा खेलता है?
jasonszhao

4

स्विफ्ट 4.2

भगवान का शुक्र है, यह हल हो गया। पाठ को बटन पर सेट करने के बाद, आप आंतरिक रूप से पुनः प्राप्त कर सकते हैं जो कि UIView से प्राकृतिक आकार है (आधिकारिक दस्तावेज यहां है )। UIButton के लिए, आप इसे नीचे की तरह उपयोग कर सकते हैं।

button.intrinsicContentSize.width

आपकी जानकारी के लिए, मैंने इसे ठीक से देखने के लिए चौड़ाई समायोजित की।

button.frame = CGRect(fx: xOffset, y: 0.0, width: button.intrinsicContentSize.width + 18, height: 40)

सिम्युलेटर

आंतरिक के साथ UIButtonsContentSize

स्रोत: https://riptutorial.com/ios/example/16418/get-uibutton-s-size-strictly-based-on-its-text-and-font


1
क्या आप थोड़ा और संदर्भ दे सकते हैं? प्रश्न में आपकी रेखा कोड से किस प्रकार संबंधित है? क्या आप यह भी बता सकते हैं कि आपके द्वारा सुझाया गया कोड क्या है? केवल स्पष्टीकरण के रूप में लिंक प्रदान करना इस साइट के लिए सही प्रारूप नहीं है ( कारणों के लिए meta.stackexchange.com/a/8259/266197 देखें ), लेकिन यदि आप कुछ स्पष्टीकरण और संदर्भ जोड़ते हैं, तो आपका उत्तर अधिक मूल्यवान हो जाएगा!
सं।

3

मुझे इस पोस्ट से संबंधित कुछ अतिरिक्त आवश्यकताएं हैं जो sizeToFitहल नहीं करती हैं। मुझे पाठ की परवाह किए बिना बटन को मूल स्थान पर केंद्रित रखने की आवश्यकता थी। मैं यह भी नहीं चाहता कि बटन अपने मूल आकार से बड़ा हो।

इसलिए, मैं बटन को उसके अधिकतम आकार के लिए लेआउट करता हूं, नियंत्रक में उस आकार को सहेजता हूं और पाठ बदलने पर बटन को आकार देने के लिए निम्न विधि का उपयोग करता हूं:

+ (void) sizeButtonToText:(UIButton *)button availableSize:(CGSize)availableSize padding:(UIEdgeInsets)padding {    

     CGRect boundsForText = button.frame;

    // Measures string
    CGSize stringSize = [button.titleLabel.text sizeWithFont:button.titleLabel.font];
    stringSize.width = MIN(stringSize.width + padding.left + padding.right, availableSize.width);

    // Center's location of button
    boundsForText.origin.x += (boundsForText.size.width - stringSize.width) / 2;
    boundsForText.size.width = stringSize.width;
    [button setFrame:boundsForText];
 }

1

पाठ के लिए ऊंचाई ऑटोरेस्ज़िंग वाला यह बटन वर्ग (ज़ामरीन के लिए लेकिन अन्य भाषा के लिए फिर से लिखा जा सकता है)

[Register(nameof(ResizableButton))]
public class ResizableButton : UIButton
{
    NSLayoutConstraint _heightConstraint;
    public bool NeedsUpdateHeightConstraint { get; private set; } = true;

    public ResizableButton(){}

    public ResizableButton(UIButtonType type) : base(type){}

    public ResizableButton(NSCoder coder) : base(coder){}

    public ResizableButton(CGRect frame) : base(frame){}

    protected ResizableButton(NSObjectFlag t) : base(t){}

    protected internal ResizableButton(IntPtr handle) : base(handle){}

    public override void LayoutSubviews()
    {
        base.LayoutSubviews();
        UpdateHeightConstraint();
        InvalidateIntrinsicContentSize();
    }

    public override void SetTitle(string title, UIControlState forState)
    {
        NeedsUpdateHeightConstraint = true;
        base.SetTitle(title, forState);
    }

    private void UpdateHeightConstraint()
    {
        if (!NeedsUpdateHeightConstraint)
            return;
        NeedsUpdateHeightConstraint = false;
        var labelSize = TitleLabel.SizeThatFits(new CGSize(Frame.Width - TitleEdgeInsets.Left - TitleEdgeInsets.Right, float.MaxValue));

        var rect = new CGRect(Frame.X, Frame.Y, Frame.Width, labelSize.Height + TitleEdgeInsets.Top + TitleEdgeInsets.Bottom);

        if (_heightConstraint != null)
            RemoveConstraint(_heightConstraint);

        _heightConstraint = NSLayoutConstraint.Create(this, NSLayoutAttribute.Height, NSLayoutRelation.Equal, 1, rect.Height);
        AddConstraint(_heightConstraint);
    }

     public override CGSize IntrinsicContentSize
     {
         get
         {
             var labelSize = TitleLabel.SizeThatFits(new CGSize(Frame.Width - TitleEdgeInsets.Left - TitleEdgeInsets.Right, float.MaxValue));
             return new CGSize(Frame.Width, labelSize.Height + TitleEdgeInsets.Top + TitleEdgeInsets.Bottom);
         }
     }
}

1

किसी कारण से, func sizeToFit()मेरे लिए काम नहीं करता है। मेरा सेट अप है मैं एक बटन UITableViewCellका उपयोग कर रहा हूं और मैं ऑटो लेआउट का उपयोग कर रहा हूं।

मेरे लिए क्या काम किया है:

  1. चौड़ाई प्राप्त करें
  2. intrinsicContentSizeचौड़ाई प्राप्त करें क्योंकि इस दस्तावेज़ के अनुसार ऑटो लेआउट के बारे में पता नहीं है intrinsicContentSize। करने के लिए चौड़ाई बाधा सेट intrinsicContentSizeचौड़ाई

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

यहाँ से दो शीर्षक हैं Debug View Hierachry यहाँ छवि विवरण दर्ज करें

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


0

सच कहूं तो मुझे लगता है कि यह वास्तव में शर्म की बात है कि स्टोरीबोर्ड में यह कहने के लिए कोई सरल चेकबॉक्स नहीं है कि आप टेक्स्ट को समायोजित करने के लिए बटन का आकार बदलना चाहते हैं। खैर जो भी हो।

यहां स्टोरीबोर्ड का उपयोग करके सबसे सरल समाधान है।

  1. UIView रखें और इसके लिए अड़चनें डालें। उदाहरण: यहाँ छवि विवरण दर्ज करें
  2. उइबेल के अंदर उइलैबेल रखें। UIView के किनारों से इसे जोड़ने के लिए बाधाओं को सेट करें।

  3. अपने UIButton को UIView के अंदर रखें। UIView के किनारों पर इसे संलग्न करने के लिए समान बाधाओं को सेट करें।

  4. UILabel की लाइनों की संख्या के लिए 0 सेट करें। यहाँ छवि विवरण दर्ज करें

  5. आउटलेट्स सेट करें।

    @IBOutlet var button: UIButton!
    @IBOutlet var textOnTheButton: UILabel!
  1. कुछ लंबे, लंबे, लंबे शीर्षक प्राप्त करें।

    let someTitle = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
  1. ViewDidLoad पर UILabel और UIButton दोनों के लिए शीर्षक निर्धारित किया है।

    override func viewDidLoad() {
        super.viewDidLoad()
        textOnTheButton.text = someTitle
        button.setTitle(someTitle, for: .normal)
        button.titleLabel?.numberOfLines = 0
    }
  1. यह सुनिश्चित करने के लिए इसे चलाएं कि बटन आकार बदल गया है और इसे दबाया जा सकता है।

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

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