iOS NSAttributedString on UIButton

前端 未结 3 491
谎友^
谎友^ 2020-12-04 13:14

I\'m using iOS 6, so attributed strings should be easy to use, right? Well... not so much.

What I want to do:

Using a custom subclass of

3条回答
  •  既然无缘
    2020-12-04 13:36

    With Swift 5.1 and iOS 13.1, you can use the UIButton subclass implementation below in order to solve your problem:

    import UIKit
    
    class CustomButton: UIButton {
    
        required init(title: String, subtitle: String) {
            super.init(frame: CGRect.zero)
    
            let style = NSMutableParagraphStyle()
            style.alignment = NSTextAlignment.center
            style.lineBreakMode = NSLineBreakMode.byWordWrapping
    
            let titleAttributes: [NSAttributedString.Key : Any] = [
                NSAttributedString.Key.foregroundColor: UIColor.label,
                NSAttributedString.Key.underlineStyle : NSUnderlineStyle.single.rawValue,
                NSAttributedString.Key.font : UIFont.preferredFont(forTextStyle: UIFont.TextStyle.largeTitle),
                NSAttributedString.Key.paragraphStyle : style
            ]
            let subtitleAttributes = [
                NSAttributedString.Key.foregroundColor: UIColor.label,
                NSAttributedString.Key.font : UIFont.preferredFont(forTextStyle: UIFont.TextStyle.body),
                NSAttributedString.Key.paragraphStyle : style
            ]
    
            let attributedString = NSMutableAttributedString(string: title, attributes: titleAttributes)
            attributedString.append(NSAttributedString(string: "\n"))
            attributedString.append(NSAttributedString(string: subtitle, attributes: subtitleAttributes))
    
            setAttributedTitle(attributedString, for: UIControl.State.normal)
            titleLabel?.numberOfLines = 0
            titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
    }
    

    Usage:

    import UIKit
    
    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let button = CustomButton(title: "Title", subtitle: "Subtitle")
            button.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(button)
    
            let horizontalConstraint = button.centerXAnchor.constraint(equalTo: view.centerXAnchor)
            let verticalConstraint = button.centerYAnchor.constraint(equalTo: view.centerYAnchor)
            NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint])
        }
    
    }
    

    As an alternative if you really need a button of type system, you may use the following code:

    import UIKit
    
    extension UIButton {
    
        static func customSystemButton(title: String, subtitle: String) -> UIButton {
            let style = NSMutableParagraphStyle()
            style.alignment = NSTextAlignment.center
            style.lineBreakMode = NSLineBreakMode.byWordWrapping
    
            let titleAttributes: [NSAttributedString.Key : Any] = [
                NSAttributedString.Key.underlineStyle : NSUnderlineStyle.single.rawValue,
                NSAttributedString.Key.font : UIFont.preferredFont(forTextStyle: UIFont.TextStyle.largeTitle),
                NSAttributedString.Key.paragraphStyle : style
            ]
            let subtitleAttributes = [
                NSAttributedString.Key.font : UIFont.preferredFont(forTextStyle: UIFont.TextStyle.body),
                NSAttributedString.Key.paragraphStyle : style
            ]
    
            let attributedString = NSMutableAttributedString(string: title, attributes: titleAttributes)
            attributedString.append(NSAttributedString(string: "\n"))
            attributedString.append(NSAttributedString(string: subtitle, attributes: subtitleAttributes))
    
            let button = UIButton(type: UIButton.ButtonType.system)
            button.setAttributedTitle(attributedString, for: UIControl.State.normal)
            button.titleLabel?.numberOfLines = 0
            button.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping
    
            return button
        }
    
    }
    

    Usage:

    import UIKit
    
    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let button = UIButton.customSystemButton(title: "Title", subtitle: "Subtitle")
            button.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(button)
    
            let horizontalConstraint = button.centerXAnchor.constraint(equalTo: view.centerXAnchor)
            let verticalConstraint = button.centerYAnchor.constraint(equalTo: view.centerYAnchor)
            NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint])
        }
    
    }
    

    The two screen shots below show the result display for the UIButton subclass (on the left) and for the system type button (on the right):

提交回复
热议问题