Swift - UIButton dengan dua baris teks


93

Saya bertanya-tanya apakah mungkin membuat UIButton dengan dua baris teks. Saya ingin setiap baris memiliki ukuran font yang berbeda. Baris pertama akan menjadi 17 poin dan yang kedua akan menjadi 11 poin. Saya sudah mencoba mengotak-atik menempatkan dua label di dalam UIButton, tetapi saya tidak bisa membuatnya tetap berada di dalam batas tombol.

Saya mencoba melakukan semua ini di pembuat ui, dan bukan secara terprogram.

Terima kasih

Jawaban:


249

Ada dua pertanyaan.

Saya bertanya-tanya apakah mungkin membuat UIButton dengan dua baris teks

Ini dimungkinkan melalui penggunaan papan cerita atau secara terprogram.

Papan cerita:

Ubah 'Line Break Mode' menjadi Character Wrap atau Word Wrap dan gunakan tombol Alt / Option + Enter untuk memasukkan baris baru di bidang Judul UIButton.

masukkan deskripsi gambar di sini

Secara terprogram:

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

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

Saya ingin setiap baris memiliki ukuran font yang berbeda 1

Kasus terburuknya adalah, Anda dapat menggunakan UIButtonkelas khusus dan menambahkan dua label di dalamnya.

Cara yang lebih baik adalah, manfaatkan NSMutableAttributedString. Perhatikan bahwa, ini hanya dapat dicapai melalui program.

Cepat 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 yang lebih tua

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

    }

Keluaran

masukkan deskripsi gambar di sini


2
Bekerja dengan baik. Sekarang saya bertanya-tanya apakah ada cara untuk memusatkan teks pada setiap baris, dan apakah ada cara untuk memasukkan lebih banyak ruang di antara dua baris.
Scott

3
Anda dapat meratakan kedua teks baris ke tengah. tulis kode berikut btnTwoLine? .titleLabel? .textAlignment = NSTextAlignment.Center atau lakukan dengan menggunakan file storyboard (control section-> Alignment)
Shamsudheen TK

bolehkah saya tahu apa tujuan meletakkan lebih banyak garis di antaranya?
Shamsudheen TK

Itu tergantung pada ukuran tombolnya. Jika tombolnya besar, maka kedua baris teks tersebut akan berada tepat di tengah, dengan banyak ruang di bagian atas dan bawah. Bukan itu tampilan yang saya inginkan.
Scott

Anda harus menerapkan beberapa trik di sini :) Anda dapat meletakkan lebih banyak baris di antara menggunakan banyak \ n. Maksud saya, "halo \ n \ n \ ndi sana" akan memberi Anda tiga spasi. namun, jangan lupa untuk mengubah kode var newlineRange: NSRange = buttonText.rangeOfString ("\ n \ n \ n")
Shamsudheen TK

22

Saya mencari topik yang hampir sama, hanya saja saya tidak memerlukan dua ukuran font yang berbeda. Jika seseorang mencari solusi sederhana:

    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

Saya melihat masalah di sebagian besar solusi yaitu saat membuat mode jeda baris ke "Bungkus Karakter", baris kedua akan dibiarkan sejajar dengan baris pertama

Untuk membuat semua garis berada di tengah. cukup ubah judul From Plain menjadi Attributed dan kemudian Anda dapat membuat setiap baris menjadi tengah

atribut judul di tengah


6

ubah hentian baris menjadi bungkus karakter, pilih tombol Anda dan di inspektur atribut pergi ke jeda baris dan ubah ke bungkus karakter

masukkan deskripsi gambar di sini


6

Sintaks 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
tidak yakin kenapa, tapi saya harus menambahkan button.titleLabel? .numberOfLines = 0
budidino

Tidak berhasil dalam 4 cepat dulu. Perlu menyetel "baris baru" menjadi "bungkus kata". Terima kasih
kawan

jawaban asli sebelumnya ada di bawah: stackoverflow.com/a/30679547/5318223
Kiril S.

5

Saya telah memperbaiki ini dan solusi saya hanya ada di Storyboard.

Perubahan:

Itu ditambahkan di Identity Inspector -> User Defined Runtime Attributes (KeyPaths ini):

  • numberOfLines = 2
  • titleLabel.textAlignment = 1

Atribut Waktu Proses yang Ditentukan Pengguna

Saya menambahkan ini di inspektur atribut:

  • jeda baris = bungkus kata

Bungkus kata


2

Anda perlu melakukan beberapa ini dalam kode. Anda tidak dapat mengatur 2 font berbeda di IB. Selain mengubah mode jeda baris menjadi bungkus karakter, Anda memerlukan sesuatu seperti ini untuk menyetel judul,

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

Salah satu cara untuk melakukannya adalah dengan label, saya rasa. Saya melakukan ini, dan tampaknya berhasil. Saya bisa membuat ini sebagai UIButton dan kemudian mengekspos labelnya, saya kira. Saya tidak tahu apakah ini masuk akal.

    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

jalanku:

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

Sayangnya, solusi yang disarankan tidak berhasil bagi saya ketika saya ingin memiliki tombol mutliline di dalam CollectionView. Kemudian seorang kolega menunjukkan kepada saya solusi yang ingin saya bagikan jika seseorang memiliki masalah yang sama - semoga ini membantu! Buat kelas yang mewarisi dari UIControl dan kembangkan dengan label, yang kemudian akan berperilaku serupa seperti tombol.

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")
    }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.