Swift - İki satır metin içeren UIB düğmesi


96

İki satırlık metinle bir UIButton oluşturmanın mümkün olup olmadığını merak ediyordum. Her satırın farklı bir yazı tipi boyutuna sahip olmasına ihtiyacım var. İlk satır 17, ikincisi 11 puan olacak. Bir UIB düğmesinin içine iki etiket koymayı denedim, ancak bunların düğmenin sınırları içinde kalmasını sağlayamıyorum.

Tüm bunları programlı olarak değil, kullanıcı arabirimi oluşturucusunda yapmaya çalışıyorum.

Teşekkürler

Yanıtlar:


259

İki soru var.

İki satır metin içeren bir UIButton oluşturmanın mümkün olup olmadığını merak ediyordum.

Bu, film şeridini kullanarak veya programlı olarak mümkündür.

Storyboard:

'Satır Kırma Modu'nu Karakter Kaydırma veya Sözcük Kaydırma olarak değiştirin ve UIButton'ın Başlık alanına yeni bir satır girmek için Alt / Option + Enter tuşunu kullanın.

görüntü açıklamasını buraya girin

Programlı olarak:

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

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

Her satırın farklı bir yazı tipi boyutuna sahip olmasına ihtiyacım var 1

En kötüsü, özel bir UIButtonsınıf kullanabilir ve içine iki etiket ekleyebilirsiniz.

Daha iyi yol, yararlanmaktır NSMutableAttributedString. Bunun yalnızca programlı olarak gerçekleştirilebileceğini unutmayın.

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: [])
}

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

    }

Çıktı

görüntü açıklamasını buraya girin


3
Harika çalışıyor. Şimdi, metni her satırda ortalamanın bir yolu olup olmadığını ve iki satır arasına daha fazla boşluk eklemenin bir yolu olup olmadığını merak ediyorum.
Scott

3
her iki satır metnini ortaya hizalayabilirsiniz. aşağıdaki kodu yazın btnTwoLine? .titleLabel? .textAlignment = NSTextAlignment.Center veya bunu storyboard dosyasını kullanarak yapın (kontrol
bölümü-

Araya daha fazla satır koymanın amacının ne olduğunu öğrenebilir miyim?
Shamsudheen TK

Bu, düğmenin boyutuna bağlıdır. Düğme büyükse, iki satırlık metin tam ortada olacak ve üstte ve altta çok fazla alan olacaktır. Aradığım bakış bu değildi.
Scott

burada bazı hileler uygulamanız gerekiyor :) birden çok kullanarak arasına daha fazla satır koyabilirsiniz \ n. Demek istediğim, "merhaba \ n \ n \ norada" size üç boşluk verecek. ancak, kodunuzu değiştirmeyi unutmayın var newlineRange: NSRange = buttonText.rangeOfString ("\ n \ n \ n")
Shamsudheen TK

23

İki farklı yazı tipi boyutuna ihtiyacım olmaması dışında neredeyse aynı konuyu arıyordum. Birinin basit bir çözüm araması durumunda:

    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

Çözümlerin çoğunda "Karakter Kaydırma" için satır sonu modu yapılırken ikinci satırın ilk satıra hizalı olarak sola hizalı olacağı bir sorun olduğunu fark ettim.

Tüm çizgileri ortalamak için. Başlığı Düzten İlişkilendirilmiş olarak değiştirin ve ardından her bir çizgiyi ortalayın

atfedilen merkezli başlık


6

satır sonunu karakter kaydırmaya değiştirin, düğmenizi seçin ve nitelik denetçisinde satır kesmesine gidin ve karakter kaydırmaya değiştirin

görüntü açıklamasını buraya girin


6

SWIFT 3 Sözdizimi

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
neden emin değilim, ama button.titleLabel? .numberOfLines = 0
budidino

Önce hızlı 4'te işe yaramadı. "Satır sonu" nun "kelime kaydırma" olarak ayarlanması gerekir. Teşekkürler dostum :)
Karan Alangat

önceki orijinal cevap aşağıdadır: stackoverflow.com/a/30679547/5318223
Kiril S.


2

Bunlardan bazılarını kodla yapmanız gerekiyor. IB'de 2 farklı yazı tipi ayarlayamazsınız. Satır sonu modunu karakter kaydırmaya değiştirmeye ek olarak, başlığı ayarlamak için buna benzer bir şeye ihtiyacınız var.

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

Bunu yapmanın bir yolu, sanırım etiketlerle. Bunu yaptım ve iyi çalışıyor gibi görünüyor. Bunu bir UIB düğmesi olarak oluşturabilir ve ardından etiketleri ortaya çıkarabilirim, sanırım. Bunun mantıklı olup olmadığını bilmiyorum.

    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

benim yolum:

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

Bir CollectionView içinde mutline butonu olmasını istediğimde önerilen çözümler maalesef benim için işe yaramadı. Sonra bir meslektaşım bana birisinin aynı sorunu yaşaması durumunda paylaşmak istediğim bir çözüm gösterdi - umarım bu yardımcı olur! UIControl'den devralan ve onu bir etiketle genişleten ve daha sonra bir düğme gibi davranan bir sınıf oluşturun.

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")
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.