Swift - UIButton với hai dòng văn bản


93

Tôi đã tự hỏi liệu có thể tạo UIButton với hai dòng văn bản hay không. Tôi cần mỗi dòng có một cỡ chữ khác nhau. Dòng đầu tiên sẽ là 17 điểm và dòng thứ hai sẽ là 11 điểm. Tôi đã thử đặt hai nhãn vào bên trong UIButton, nhưng tôi không thể làm cho chúng ở bên trong giới hạn của nút.

Tôi đang cố gắng thực hiện tất cả điều này trong trình tạo ui chứ không phải theo chương trình.

Cảm ơn

Câu trả lời:


247

Có hai câu hỏi.

Tôi đã tự hỏi liệu có thể tạo UIButton với hai dòng văn bản không

Điều này có thể thực hiện được bằng cách sử dụng bảng phân cảnh hoặc theo chương trình.

Bảng phân cảnh:

Thay đổi 'Chế độ ngắt dòng' thành Gói ký tự hoặc Gói từ và sử dụng phím Alt / Option + Enter để nhập một dòng mới trong trường Tiêu đề của UIButton.

nhập mô tả hình ảnh ở đây

Lập trình:

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

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

Tôi cần mỗi dòng có một kích thước phông chữ khác nhau 1

Trường hợp xấu nhất là bạn có thể sử dụng một UIButtonlớp tùy chỉnh và thêm hai nhãn bên trong nó.

Cách tốt hơn là hãy tận dụng NSMutableAttributedString. Lưu ý rằng, chỉ có thể đạt được điều này bằng cách lập trình.

Swift 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 cũ hơn

@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)

    }

Đầu ra

nhập mô tả hình ảnh ở đây


2
Hoạt động tuyệt vời. Bây giờ tôi đang tự hỏi liệu có cách nào để căn giữa văn bản trên mỗi dòng và có cách nào để chèn thêm khoảng cách giữa hai dòng không.
Scott

3
bạn có thể căn chỉnh cả hai dòng văn bản vào giữa. viết đoạn mã sau btnTwoLine .titleLabel .textAlignment = NSTextAlignment.Center hoặc làm điều đó bằng cách sử dụng tập tin kịch bản (điều khiển section-> Alignment)?
Shamsudheen TK

Tôi có thể biết mục đích của việc đặt thêm dòng vào giữa là gì không?
Shamsudheen TK

Nó phụ thuộc vào kích thước của nút. Nếu nút lớn, thì hai dòng văn bản sẽ nằm ngay chính giữa, có nhiều khoảng trống ở trên và dưới. Đó không phải là cái nhìn mà tôi đã định.
Scott

bạn phải áp dụng một số thủ thuật ở đây :) bạn có thể đặt nhiều dòng hơn giữa việc sử dụng nhiều \ n. Ý tôi là, "xin chào \ n \ n \ nthere" sẽ cho bạn ba khoảng trắng. tuy nhiên, đừng quên sửa đổi mã của bạn var newlineRange: NSRange = buttonText.rangeOfString ("\ n \ n \ n")
Shamsudheen TK

22

Tôi đã tìm kiếm gần như cùng một chủ đề, ngoại trừ việc tôi không cần hai cỡ chữ khác nhau. Trong trường hợp ai đó đang tìm kiếm một giải pháp đơn giản:

    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)

12

Tôi nhận thấy một vấn đề trong hầu hết các giải pháp đó là trong khi đặt chế độ ngắt dòng thành "Character Wrap", dòng thứ hai sẽ được căn trái với dòng đầu tiên

Để làm cho tất cả các dòng được căn giữa. chỉ cần thay đổi tiêu đề Từ Đồng bằng thành Thuộc tính và sau đó bạn có thể căn giữa từng dòng

tiêu đề được phân bổ ở giữa


6

thay đổi ngắt dòng thành bọc ký tự, chọn nút của bạn và trong trình kiểm tra thuộc tính, chuyển đến ngắt dòng và thay đổi nó thành ký tự bọc

nhập mô tả hình ảnh ở đây


6

Cú pháp 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
không chắc chắn lý do tại sao, nhưng tôi đã có thêm button.titleLabel .numberOfLines = 0?
budidino

Không hoạt động trong nhanh 4 đầu tiên. Cần đặt "ngắt dòng" thành "bọc từ". Cảm ơn người đàn ông :)
Karan Alangat 14/12/18

câu trả lời ban đầu trước đó là bên dưới: stackoverflow.com/a/30679547/5318223
Kiril S.

5

Tôi đã sửa lỗi này và giải pháp của tôi chỉ có trong Bảng phân cảnh.

Các thay đổi:

Nó được thêm vào Trình kiểm tra danh tính -> Thuộc tính thời gian chạy do người dùng xác định (các Đường dẫn khóa này):

  • numberOfLines = 2
  • titleLabel.textAlignment = 1

Thuộc tính thời gian chạy do người dùng xác định

Tôi đã thêm điều này trong trình kiểm tra thuộc tính:

  • ngắt dòng = gói từ

Bọc từ


2

Bạn cần thực hiện một số điều này trong mã. bạn không thể đặt 2 phông chữ khác nhau trong IB. Ngoài việc thay đổi chế độ ngắt dòng thành bao bọc ký tự, bạn cần một cái gì đó như thế này để đặt tiêu đề,

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

Tôi đoán là có một cách để làm điều đó với nhãn. Tôi đã làm điều này, và nó có vẻ hoạt động tốt. Tôi có thể tạo cái này dưới dạng UIButton và sau đó hiển thị các nhãn, tôi đoán vậy. Tôi không biết liệu điều này có ý nghĩa gì không.

    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

theo cách của tôi:

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

Rất tiếc, các giải pháp được đề xuất đã không phù hợp với tôi khi tôi muốn có nút mutliline bên trong CollectionView. Sau đó, một đồng nghiệp đã chỉ cho tôi một cách giải quyết mà tôi muốn chia sẻ trong trường hợp ai đó gặp vấn đề tương tự - hy vọng điều này sẽ hữu ích! Tạo một lớp kế thừa từ UIControl và mở rộng nó bằng một nhãn, sau đó sẽ hoạt động tương tự như một nút.

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")
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.