سؤال

لدي الكود التالي ...

UILabel *buttonLabel = [[UILabel alloc] initWithFrame:targetButton.bounds];
buttonLabel.text = @"Long text string";
[targetButton addSubview:buttonLabel];
[targetButton bringSubviewToFront:buttonLabel];

...الفكرة هي أنه يمكنني الحصول على نص متعدد الأسطر للزر، ولكن النص دائمًا ما يكون محجوبًا بواسطة صورة خلفية زر UIButton.يُظهر استدعاء التسجيل لإظهار طرق العرض الفرعية للزر أنه تمت إضافة UILabel، ولكن لا يمكن رؤية النص نفسه.هل هذا خطأ في UIButton أم أنني أفعل شيئًا خاطئًا؟

هل كانت مفيدة؟

المحلول

بالنسبة لنظام التشغيل iOS 6 والإصدارات الأحدث، استخدم ما يلي للسماح بعدة أسطر:

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
// you probably want to center it
button.titleLabel.textAlignment = NSTextAlignmentCenter; // if you want to 
[button setTitle: @"Line1\nLine2" forState: UIControlStateNormal];

بالنسبة لنظام التشغيل iOS 5 والإصدارات الأقدم، استخدم ما يلي للسماح بعدة أسطر:

button.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
// you probably want to center it
button.titleLabel.textAlignment = UITextAlignmentCenter;
[button setTitle: @"Line1\nLine2" forState: UIControlStateNormal];

2017، لنظام iOS9 للأمام,

بشكل عام، فقط افعل هذين الأمرين:

  1. يختار "النص المنسوب"
  2. في القائمة المنبثقة "فاصل الأسطر"، حدد "التفاف الكلمات"

نصائح أخرى

والجواب المختارة صحيحة ولكن إذا كنت تفضل أن تفعل هذا النوع من شيء في واجهة باني يمكنك القيام بذلك:

إذا كنت ترغب في إضافة زر تحت عنوان تركزت مع خطوط متعددة، تعيين إعدادات واجهة البناء الخاص بك للزر:

[]

لIOS 6:

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.textAlignment = NSTextAlignmentCenter;

كما

UILineBreakModeWordWrap and UITextAlignmentCenter

ويتم إهمال في IOS 6 فصاعدا ..

لأكرر اقتراح روجر نولان، ولكن مع رمز واضح، وهذا هو الحل العام:

button.titleLabel?.numberOfLines = 0

تحليل SWIFT 3

button.titleLabel?.lineBreakMode = .byWordWrapping
button.titleLabel?.textAlignment = .center  
button.setTitle("Button\nTitle",for: .normal)

وهناك طريقة أسهل بكثير:

someButton.lineBreakMode = UILineBreakModeWordWrap;

و(تحرير لدائرة الرقابة الداخلية 3 و في وقت لاحق:)

someButton.titleLabel.lineBreakMode = UILineBreakModeWordWrap;

واليسار محاذاة على iOS7 مع التخطيط التلقائي:

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.textAlignment = NSTextAlignmentLeft;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;

وأولا وقبل كل شيء، يجب أن تكون على علم بأن UIButton لديها بالفعل UILabel داخله. يمكنك تعيين باستخدام –setTitle:forState:.

والمشكلة مع المثال الخاص بك هي التي تحتاج إلى تعيين الخاصية numberOfLines UILabel إلى شيء آخر من قيمته الافتراضية من 1. يجب عليك أيضا مراجعة الملكية lineBreakMode.

في Xcode 9.3 يمكنك القيام بذلك باستخدام القصة المصورة مثل أدناه،

enter image description here

تحتاج إلى ضبط محاذاة نص عنوان الزر إلى المركز

button.titleLabel?.textAlignment = .center

لا تحتاج إلى تعيين نص العنوان بسطر جديد ( ) كما هو موضح أدناه،

button.setTitle("Good\nAnswer",for: .normal)

ببساطة تحديد العنوان،

button.setTitle("Good Answer",for: .normal)

وهنا النتيجة،

enter image description here

وبالنسبة لأولئك الذين يستخدمون القصة المصورة كسكودي 4، يمكنك النقر على زر، وعلى الجانب الأيمن المرافق جزء سمات تحت المفتش، سترى خيار لخط فاصل. اختيار التفاف، ويجب أن تكون على ما يرام.

وأجوبة هنا اقول لكم كيفية تحقيق لقب زر متعدد الأسطر برمجيا.

وأنا فقط أريد أن أضيف أنه إذا كنت تستخدم القصص المصورة، يمكنك كتابة [السيطرة + أدخل] لفرض سطر جديد في حقل عنوان زر.

وHTH

ويجب عليك إضافة هذا الرمز:

buttonLabel.titleLabel.numberOfLines = 0;

وأما بالنسبة لفكرة برنت للوضع عنوان UILabel كما عرض الأخوة، لا يبدو لي وكأنه فكرة جيدة للغاية. وأظل أفكر في مشاكل التفاعل مع UILabel بسبب أحداث لمسة لا تحصل من خلال وجهة نظر UIButton ل.

من ناحية أخرى، مع UILabel كما subview من UIButton، أنا ترحيبي جدا مع العلم أن سوف يكون دائما نشر أحداث اللمس لsuperview وUILabel ل.

وأنا لم تأخذ هذا النهج ولم يلاحظوا أي من مشكلات تم الإبلاغ عنها مع backgroundImage. وأضاف لي هذا الرمز في -titleRectForContentRect: من فئة فرعية UIButton ولكن يمكن أيضا أن توضع التعليمات البرمجية في رسم روتين superview UIButton، والتي في هذه الحالة يجب عليك استبدال جميع الإشارات إلى الذات مع المتغير UIButton ل

.
#define TITLE_LABEL_TAG 1234

- (CGRect)titleRectForContentRect:(CGRect)rect
{   
    // define the desired title inset margins based on the whole rect and its padding
    UIEdgeInsets padding = [self titleEdgeInsets];
    CGRect titleRect = CGRectMake(rect.origin.x    + padding.left, 
                                  rect.origin.x    + padding.top, 
                                  rect.size.width  - (padding.right + padding.left), 
                                  rect.size.height - (padding.bottom + padding].top));

    // save the current title view appearance
    NSString *title = [self currentTitle];
    UIColor  *titleColor = [self currentTitleColor];
    UIColor  *titleShadowColor = [self currentTitleShadowColor];

    // we only want to add our custom label once; only 1st pass shall return nil
    UILabel  *titleLabel = (UILabel*)[self viewWithTag:TITLE_LABEL_TAG];


    if (!titleLabel) 
    {
        // no custom label found (1st pass), we will be creating & adding it as subview
        titleLabel = [[UILabel alloc] initWithFrame:titleRect];
        [titleLabel setTag:TITLE_LABEL_TAG];

        // make it multi-line
        [titleLabel setNumberOfLines:0];
        [titleLabel setLineBreakMode:UILineBreakModeWordWrap];

        // title appearance setup; be at will to modify
        [titleLabel setBackgroundColor:[UIColor clearColor]];
        [titleLabel setFont:[self font]];
        [titleLabel setShadowOffset:CGSizeMake(0, 1)];
        [titleLabel setTextAlignment:UITextAlignmentCenter];

        [self addSubview:titleLabel];
        [titleLabel release];
    }

    // finally, put our label in original title view's state
    [titleLabel setText:title];
    [titleLabel setTextColor:titleColor];
    [titleLabel setShadowColor:titleShadowColor];

    // and return empty rect so that the original title view is hidden
    return CGRectZero;
}

وفعلت تأخذ من الوقت وكتب أكثر قليلا عن هذا <وأ href = "http://unsolicitedfeedback.com/2009/03/09/how-to-set-a-multi-line-title-in- uibutton "يختلط =" نوفولو noreferrer "> هنا . هناك، وأود أيضا أن أشير إلى حل أقصر، على الرغم من أنها لا تناسب تماما جميع السيناريوهات وينطوي على بعض وجهات النظر خاصة القرصنة. أيضا هناك، يمكنك تحميل فرعية UIButton جاهزة للاستعمال.

إذا كنت تستخدم لصناعة السيارات في التخطيط في دائرة الرقابة الداخلية 6 قد تحتاج أيضا إلى تعيين الخاصية preferredMaxLayoutWidth:

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.textAlignment = NSTextAlignmentCenter;
button.titleLabel.preferredMaxLayoutWidth = button.frame.size.width;

وهو يعمل تماما.

وإضافة إلى استخدام هذا مع ملف التكوين مثل PLIST، تحتاج إلى استخدام CDATA لكتابة عنوان multilined، مثل هذا:

<string><![CDATA[Line1
Line2]]></string>

ووضع lineBreakMode إلى NSLineBreakByWordWrapping (إما في IB أو رمز) يجعل التسمية زر متعدد، ولكن لا يؤثر إطار الزر.

إذا زر لديه عنوان دينامية، هناك خدعة واحد: وضع UILabel خفية مع نفس الخط وربطة عنق انها الارتفاع إلى ارتفاع زر مع تخطيط. وعندما وضعت النص إلى زر والتسمية والتخطيط التلقائي جعل كل عمل.

<قوية> ملاحظة

والجوهرية ارتفاع حجم زر من سطر واحد أكبر من التسمية، وذلك لمنع ارتفاع التسمية يتقلص انها العمودية المحتوى المعانقة الأولوية يجب أن تكون أكبر من المحتوى الزر الرأسي ضغط المقاومة.

إذا كنت تستخدم لصناعة السيارات في التخطيط.

button.titleLabel?.adjustsFontSizeToFitWidth = true
button.titleLabel?.numberOfLines = 2

وكان لي مشكلة مع لصناعة السيارات في التخطيط، وبعد تمكين متعدد الخطوط كانت النتيجة كالتالي:

وبالتالي فإن حجم titleLabel لا يؤثر على حجم زر
واضاف لقد Constraints على أساس contentEdgeInsets (في هذه الحالة contentEdgeInsets كان (10، 10، 10، 10)
بعد استدعاء makeMultiLineSupport():

نأمل أن تساعدك في (سويفت 5.0):

extension UIButton {

    func makeMultiLineSupport() {
        guard let titleLabel = titleLabel else {
            return
        }
        titleLabel.numberOfLines = 0
        titleLabel.setContentHuggingPriority(.required, for: .vertical)
        titleLabel.setContentHuggingPriority(.required, for: .horizontal)
        addConstraints([
            .init(item: titleLabel,
                  attribute: .top,
                  relatedBy: .greaterThanOrEqual,
                  toItem: self,
                  attribute: .top,
                  multiplier: 1.0,
                  constant: contentEdgeInsets.top),
            .init(item: titleLabel,
                  attribute: .bottom,
                  relatedBy: .greaterThanOrEqual,
                  toItem: self,
                  attribute: .bottom,
                  multiplier: 1.0,
                  constant: contentEdgeInsets.bottom),
            .init(item: titleLabel,
                  attribute: .left,
                  relatedBy: .greaterThanOrEqual,
                  toItem: self,
                  attribute: .left,
                  multiplier: 1.0,
                  constant: contentEdgeInsets.left),
            .init(item: titleLabel,
                  attribute: .right,
                  relatedBy: .greaterThanOrEqual,
                  toItem: self,
                  attribute: .right,
                  multiplier: 1.0,
                  constant: contentEdgeInsets.right)
            ])
    }

}

وهذه الأيام، إذا كنت حقا بحاجة الى هذا النوع من الاشياء لتكون في متناول في واجهة البناء على أساس كل حالة على حدة، يمكنك أن تفعل ذلك مع امتداد بسيط مثل هذا:

extension UIButton {
    @IBInspectable var numberOfLines: Int {
        get { return titleLabel?.numberOfLines ?? 1 }
        set { titleLabel?.numberOfLines = newValue }
    }
}

وبعد ذلك يمكنك ببساطة وضع numberOfLines كسمة على أي UIButton أو UIButton فرعية كما لو كانت التسمية. الشيء نفسه ينطبق على مجموعة كاملة من القيم عادة ما يصعب الوصول إليها أخرى، مثل دائرة نصف قطرها زاوية طبقة من طريقة العرض، أو سمات الظل الذي كان يلقي.

ولفة فئة زر الخاصة بك. انها حتى الآن أفضل حل على المدى الطويل. UIButton والطبقات UIKit أخرى مقيدة جدا في الطريقة التي يمكن تخصيصها.

self.btnError.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping

self.btnError.titleLabel?.textAlignment = .center

self.btnError.setTitle("Title", for: .normal)

وسريعة 4.0

btn.titleLabel?.lineBreakMode = .byWordWrapping
btn.titleLabel?.textAlignment = .center
btn.setTitle( "Line1\nLine2", for: .normal)

وأنا أدرج jessecurry في الإجابة ضمن <لأ href = "https://github.com/Stunner/STAControls/blob /master/STAControls/STAControls/Button/STAButton.h "يختلط =" نوفولو noreferrer "> STAButton التي هي جزء من بلادي <لأ href =" https://github.com/Stunner/STAControls "يختلط =" نوفولو noreferrer "> STAControls مكتبة مفتوحة المصدر. أنا حاليا استخدامه ضمن واحدة من التطبيقات وأنا النامية، وأنه يعمل لاحتياجاتي. لا تتردد في فتح قضايا حول كيفية تحسينه أو ترسل لي سحب الطلبات.

في سويفت 5.0 و اكس كود 10.2

SharedClass مثال الكتابة مرة واحدة واستخدام كل الأدوات

هذه هي صفك المشترك (مثل هذا تستخدم جميع خصائص المكونات)

import UIKit

class SharedClass: NSObject {

     static let sharedInstance = SharedClass()

     private override init() {

     }
  }

//UIButton extension
extension UIButton {
     //UIButton properties
     func btnMultipleLines() {
         titleLabel?.numberOfLines = 0
         titleLabel?.lineBreakMode = .byWordWrapping
         titleLabel?.textAlignment = .center        
     }
}

في الخاص بك ViewController اتصل بهذه الطريقة

button.btnMultipleLines()//This is your button

وعلى الرغم من أنه بخير لإضافة subview إلى عنصر تحكم، وليس هناك ضمان انها سوف تعمل في الواقع، لأن السيطرة قد لا يتوقع أن يكون هناك وبالتالي قد تتصرف بشكل سيئ. إذا كنت تستطيع أن تفلت من العقاب، مجرد إضافة تسمية كطريقة عرض أخ من الزر وعين إطاره بحيث يتراكب الزر. طالما تم ضبطه لتظهر في أعلى زر، لا شيء على زر يمكن القيام به يحجب ذلك.

وبعبارة أخرى:

[button.superview addSubview:myLabel];
myLabel.center = button.center;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top