Swift - UIButton พร้อมข้อความสองบรรทัด


96

ฉันสงสัยว่าเป็นไปได้ไหมที่จะสร้าง UIButton ที่มีข้อความสองบรรทัด ฉันต้องการให้แต่ละบรรทัดมีขนาดตัวอักษรที่แตกต่างกัน บรรทัดแรกจะเป็น 17 จุดและบรรทัดที่สองจะเป็น 11 จุด ฉันได้ลองยุ่งกับการใส่สองป้ายกำกับภายใน UIButton แต่ฉันไม่สามารถทำให้มันอยู่ในขอบเขตของปุ่มได้

ฉันกำลังพยายามทำทั้งหมดนี้ในตัวสร้าง UI ไม่ใช่โดยใช้โปรแกรม

ขอบคุณ

คำตอบ:


259

มีคำถามสองข้อ

ฉันสงสัยว่าเป็นไปได้ไหมที่จะสร้าง UIButton ที่มีข้อความสองบรรทัด

สามารถทำได้โดยใช้สตอรีบอร์ดหรือโดยใช้โปรแกรม

สตอรี่บอร์ด:

เปลี่ยน 'Line Break Mode' เป็นCharacter WrapหรือWord Wrapและใช้ปุ่ม Alt / Option + Enterเพื่อป้อนบรรทัดใหม่ในฟิลด์ชื่อของ UIButton

ป้อนคำอธิบายภาพที่นี่

โดยทางโปรแกรม:

override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        btnTwoLine?.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping;
}

ฉันต้องการให้แต่ละบรรทัดมีขนาดตัวอักษรที่แตกต่างกัน 1

กรณีที่เลวร้ายที่สุดคือคุณสามารถใช้UIButtonคลาสที่กำหนดเองและเพิ่มป้ายกำกับสองป้ายภายในได้

วิธีที่ดีกว่าคือใช้ประโยชน์จากNSMutableAttributedStringไฟล์. โปรดทราบว่าสิ่งนี้สามารถทำได้โดยใช้โปรแกรมเท่านั้น

สวิฟต์ 5:

@IBOutlet weak var btnTwoLine: UIButton?

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    //applying the line break mode
    textResponseButton?.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping;
    let buttonText: NSString = "hello\nthere"

    //getting the range to separate the button title strings
    let newlineRange: NSRange = buttonText.range(of: "\n")

    //getting both substrings
    var substring1 = ""
    var substring2 = ""

    if(newlineRange.location != NSNotFound) {
        substring1 = buttonText.substring(to: newlineRange.location)
        substring2 = buttonText.substring(from: newlineRange.location)
    }

    //assigning diffrent fonts to both substrings
    let font1: UIFont = UIFont(name: "Arial", size: 17.0)!
    let attributes1 = [NSMutableAttributedString.Key.font: font1]
    let attrString1 = NSMutableAttributedString(string: substring1, attributes: attributes1)

    let font2: UIFont = UIFont(name: "Arial", size: 11.0)!
    let attributes2 = [NSMutableAttributedString.Key.font: font2]
    let attrString2 = NSMutableAttributedString(string: substring2, attributes: attributes2)

    //appending both attributed strings
    attrString1.append(attrString2)

    //assigning the resultant attributed strings to the button
    textResponseButton?.setAttributedTitle(attrString1, for: [])
}

Swift รุ่นเก่า

@IBOutlet weak var btnTwoLine: UIButton?

override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        //applying the line break mode
        btnTwoLine?.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping;

        var buttonText: NSString = "hello\nthere"

        //getting the range to separate the button title strings
        var newlineRange: NSRange = buttonText.rangeOfString("\n")

        //getting both substrings
        var substring1: NSString = ""
        var substring2: NSString = ""

        if(newlineRange.location != NSNotFound) {
            substring1 = buttonText.substringToIndex(newlineRange.location)
            substring2 = buttonText.substringFromIndex(newlineRange.location)
        }

        //assigning diffrent fonts to both substrings
        let font:UIFont? = UIFont(name: "Arial", size: 17.0)
        let attrString = NSMutableAttributedString(
            string: substring1 as String,
            attributes: NSDictionary(
                object: font!,
                forKey: NSFontAttributeName) as [NSObject : AnyObject])

        let font1:UIFont? = UIFont(name: "Arial", size: 11.0)
        let attrString1 = NSMutableAttributedString(
            string: substring2 as String,
            attributes: NSDictionary(
                object: font1!,
                forKey: NSFontAttributeName) as [NSObject : AnyObject])

        //appending both attributed strings
        attrString.appendAttributedString(attrString1)

        //assigning the resultant attributed strings to the button
        btnTwoLine?.setAttributedTitle(attrString, forState: UIControlState.Normal)

    }

เอาต์พุต

ป้อนคำอธิบายภาพที่นี่


3
ใช้งานได้ดี ตอนนี้ฉันกำลังสงสัยว่ามีวิธีใดบ้างที่จะทำให้ข้อความในแต่ละบรรทัดอยู่ตรงกลางและมีวิธีใดที่จะแทรกช่องว่างระหว่างสองบรรทัดได้มากขึ้น
Scott

3
คุณสามารถจัดแนวข้อความทั้งสองบรรทัดให้อยู่กึ่งกลาง เขียนโค้ดต่อไปนี้ btnTwoLine? .titleLabel? .textAlignment = NSTextAlignment.Center หรือทำโดยใช้ไฟล์ storyboard (ส่วนควบคุม -> Alignment)
Shamsudheen TK

ฉันขอทราบได้ไหมว่าอะไรคือจุดประสงค์ของการวางบรรทัดเพิ่มเติมระหว่าง?
Shamsudheen TK

ขึ้นอยู่กับขนาดของปุ่ม ถ้าปุ่มใหญ่แสดงว่าข้อความทั้งสองบรรทัดจะอยู่ตรงกลางพอดีโดยมีช่องว่างด้านบนและด้านล่างมาก นั่นไม่ใช่รูปลักษณ์ที่ฉันต้องการ
Scott

คุณต้องใช้เทคนิคบางอย่างที่นี่ :) คุณสามารถเพิ่มบรรทัดระหว่างการใช้หลาย \ n ฉันหมายถึง "สวัสดี \ n \ n \ n ที่นี่" จะให้คุณมีช่องว่างสามช่อง อย่างไรก็ตามอย่าลืมแก้ไขโค้ดของคุณ var newlineRange: NSRange = buttonText.rangeOfString ("\ n \ n \ n")
Shamsudheen TK

23

ฉันกำลังมองหาเกือบหัวข้อเดียวกันยกเว้นว่าฉันไม่ต้องการขนาดตัวอักษรที่แตกต่างกันสองขนาด เผื่อว่าใครกำลังมองหาวิธีง่ายๆ:

    let button = UIButton()
    button.titleLabel?.numberOfLines = 0
    button.titleLabel?.lineBreakMode = .byWordWrapping
    button.setTitle("Foo\nBar", for: .normal)
    button.titleLabel?.textAlignment = .center
    button.sizeToFit()
    button.addTarget(self, action: #selector(rightBarButtonTapped), for: .allEvents)
    navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button)

13

ฉันสังเกตเห็นปัญหาในวิธีแก้ปัญหาส่วนใหญ่ซึ่งในขณะที่สร้างโหมดแบ่งบรรทัดเป็น "การตัดอักขระ" บรรทัดที่สองจะถูกจัดชิดซ้ายกับบรรทัดแรก

เพื่อให้เส้นทั้งหมดอยู่กึ่งกลาง เพียงแค่เปลี่ยนชื่อเรื่องจากธรรมดาเป็นแสดงที่มาจากนั้นคุณสามารถกำหนดให้แต่ละบรรทัดอยู่กึ่งกลางได้

ระบุชื่อที่อยู่กึ่งกลาง


6

เปลี่ยนการแบ่งบรรทัดเป็นการตัดอักขระเลือกปุ่มของคุณและในตัวตรวจสอบแอตทริบิวต์ไปที่ตัวแบ่งบรรทัดและเปลี่ยนเป็นการตัดอักขระ

ป้อนคำอธิบายภาพที่นี่


6

ไวยากรณ์ SWIFT 3

let str = NSMutableAttributedString(string: "First line\nSecond Line")
str.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: 17), range: NSMakeRange(0, 10))
str.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: 12), range: NSMakeRange(11, 11))
button.setAttributedTitle(str, for: .normal)

2
ไม่แน่ใจว่าทำไม แต่ฉันต้องเพิ่ม button.titleLabel? .numberOfLines = 0
budidino

ไม่ทำงานใน swift 4 ก่อน ต้องตั้งค่า "ตัวแบ่งบรรทัด" เป็น "ตัดคำ" Thanks man :)
Karan Alangat

คำตอบเดิมก่อนหน้านี้อยู่ด้านล่าง: stackoverflow.com/a/30679547/5318223
Kiril S.

5

ฉันได้แก้ไขปัญหานี้แล้วและวิธีแก้ปัญหาของฉันอยู่ใน Storyboard เท่านั้น

การเปลี่ยนแปลง:

เพิ่มในIdentity Inspector -> User Defined Runtime Attributes (KeyPaths เหล่านี้):

  • numberOfLines = 2
  • titleLabel.textAlignment = 1

คุณสมบัติรันไทม์ที่ผู้ใช้กำหนด

ฉันเพิ่มสิ่งนี้ในตัวตรวจสอบคุณสมบัติ:

  • ตัวแบ่งบรรทัด = ตัดคำ

ตัดคำ


2

คุณต้องทำบางส่วนในโค้ด คุณไม่สามารถตั้งค่าแบบอักษร 2 แบบใน IB นอกเหนือจากการเปลี่ยนโหมดตัวแบ่งบรรทัดเป็นการตัดตัวอักษรคุณต้องมีสิ่งนี้เพื่อตั้งชื่อ

override func viewDidLoad() {
        super.viewDidLoad()
        var str = NSMutableAttributedString(string: "First line\nSecond Line")
        str.addAttribute(NSFontAttributeName, value: UIFont.systemFontOfSize(17), range: NSMakeRange(0, 10))
        str.addAttribute(NSFontAttributeName, value: UIFont.systemFontOfSize(12), range: NSMakeRange(11, 11))
        button.setAttributedTitle(str, forState: .Normal)

    }

1

วิธีหนึ่งที่จะทำคือการใช้ป้ายกำกับฉันเดา ฉันทำสิ่งนี้และดูเหมือนว่าจะได้ผล ฉันสามารถสร้างสิ่งนี้เป็น UIButton แล้วเปิดเผยป้ายกำกับฉันเดา ฉันไม่รู้ว่ามันสมเหตุสมผลไหม

    let firstLabel = UILabel()

    firstLabel.backgroundColor = UIColor.lightGrayColor()
    firstLabel.text = "Hi"
    firstLabel.textColor = UIColor.blueColor()
    firstLabel.textAlignment = NSTextAlignment.Center
    firstLabel.frame = CGRectMake(0, testButton.frame.height * 0.25, testButton.frame.width, testButton.frame.height * 0.2)
    testButton.addSubview(firstLabel)

    let secondLabel = UILabel()

    secondLabel.backgroundColor = UIColor.lightGrayColor()
    secondLabel.textColor = UIColor.blueColor()
    secondLabel.font = UIFont(name: "Arial", size: 12)
    secondLabel.text = "There"
    secondLabel.textAlignment = NSTextAlignment.Center
    secondLabel.frame = CGRectMake(0, testButton.frame.height * 0.5, testButton.frame.width, testButton.frame.height * 0.2)
    testButton.addSubview(secondLabel)

0

ทางของฉัน:

func setButtonTitle(title: String, subtitle: String, button: UIButton){
        //applying the line break mode
        button.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping;
        let title = NSMutableAttributedString(string: title, attributes: Attributes.biggestLabel)
        let subtitle = NSMutableAttributedString(string: subtitle, attributes: Attributes.label)
        let char = NSMutableAttributedString(string: "\n", attributes: Attributes.biggestLabel)
        title.append(char)
        title.append(subtitle)
        button.setAttributedTitle(title, for: .normal)
    }

0

น่าเสียดายที่โซลูชันที่แนะนำใช้ไม่ได้ผลสำหรับฉันเมื่อฉันต้องการมีปุ่ม mutliline ภายใน CollectionView จากนั้นเพื่อนร่วมงานก็แสดงวิธีแก้ปัญหาที่ฉันอยากจะแบ่งปันเผื่อว่ามีคนมีปัญหาเดียวกัน - หวังว่านี่จะช่วยได้! สร้างคลาสที่สืบทอดมาจาก UIControl และขยายด้วยเลเบลซึ่งจะทำงานคล้ายกับปุ่ม

class MultilineButton: UIControl {

    let label: UILabel = {
        $0.translatesAutoresizingMaskIntoConstraints = false
        $0.numberOfLines = 0
        $0.textAlignment = .center
        return $0
    }(UILabel())

    override init(frame: CGRect) {
        super.init(frame: frame)

        addSubview(label)

        NSLayoutConstraint.activate([
            label.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
            label.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
            label.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor),
            label.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor)
        ])
    }

    override var isHighlighted: Bool {
        didSet {
            backgroundColor = backgroundColor?.withAlphaComponent(isHighlighted ? 0.7 : 1.0)
            label.textColor = label.textColor.withAlphaComponent(isHighlighted ? 0.7 : 1.0)
        }
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.