Adding NSMutableAttributedString into a TextField - ios

I have a custom UITextfield which I want when the user finishes typing, a small "R$" must be added at the begging of the text with different size.
I call the method to add the "R$" like this:
self.addTarget(self, action: #selector(setCurrencyLabelPosition), for: .editingDidEnd)
and then I try to change the attributes and content like this:
func setCurrencyLabelPosition(){
let fullText:String = "R$\((self.text)!)"
self.text = fullText
var attribute:NSMutableAttributedString = NSMutableAttributedString(attributedString:self.attributedText!)
attribute.addAttribute(NSFontAttributeName, value:UIFont.systemFont(ofSize: 12), range: NSRange(location: 0, length: 2))
self.attributedText = attribute
}
the original text of this textfield is set for size 40.0, I want only the "R$" to be of size 12.0
The problem I'm facing is that the whole text gets the size 40.0
It prints the "R$" but the size of 40.
Is it possible to do what I'm trying to using NSMutableAttributedString?

I had been working on your question, I think there is a bug in UITextField because if you modify the font to bigger font it works but if you do so but for small font then don't work.
I have done a custom class and added some customizable Inspectable properties, hope this finally help you
This is how looks, Note: the glitch is because of my gif converter
import UIKit
#IBDesignable
class CustomTextField: UITextField {
#IBInspectable var prefix : String = ""
#IBInspectable var removePrefixOnEditing : Bool = true
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func awakeFromNib() {
super.awakeFromNib()
self.addTarget(self, action: #selector(setCurrencyLabelPosition), for: .editingDidEnd)
self.addTarget(self, action: #selector(removePrefix), for: .editingDidBegin)
}
func removePrefix(){
if self.attributedText != nil
{
if(self.removePrefixOnEditing)
{
self.defaultTextAttributes = [NSFontAttributeName : UIFont.systemFont(ofSize: 20)]
let prefixRange = NSString(string: (self.attributedText?.string)!).range(of: prefix)
if(prefixRange.location != NSNotFound)
{
self.attributedText = NSAttributedString(string: (self.attributedText?.string.replacingOccurrences(of: prefix, with: ""))!, attributes: self.defaultTextAttributes)
}
}
}
}
func setCurrencyLabelPosition(){
if self.attributedText != nil
{
var fullText:String = "\((self.attributedText?.string)!)"
if(NSString(string: (self.attributedText?.string)!).range(of: prefix).location == NSNotFound)
{
fullText = "\(prefix)\((self.attributedText?.string)!)"
}
//hacky part, seems to be a bug in UITextField
self.defaultTextAttributes = [NSFontAttributeName : UIFont.systemFont(ofSize: 10)]
self.attributedText = NSAttributedString(attributedString: self.changeFontForText(originalText: fullText, text: prefix, basicFont: UIFont.systemFont(ofSize: 20), newFont: UIFont.systemFont(ofSize: 12)))
}
}
func changeFontForText(originalText:String,text:String,basicFont:UIFont, newFont:UIFont) -> NSMutableAttributedString
{
let resultAttributedString = NSMutableAttributedString(string: originalText, attributes: [NSFontAttributeName : basicFont])
let range = NSString(string: originalText).range(of: text)
if(range.location != NSNotFound)
{
resultAttributedString.setAttributes([NSFontAttributeName:newFont], range: range)
}
return resultAttributedString
}
}
Hope this helps

Related

Subclass UIButton with system font, bold, and kerning

You have to use attributed text to do kerning. But. On the other hand, you can't get at system fonts in the IB attributed text menu.
How do I make (in code) a UIButton which has
system font, weight bold
size 11
kern attribute set to -2
Ideally it would collect the text of the button from plain text Title in IB. But if the text has to be set in code that is fine.
class NiftyButton: UIButton {
????
}
Normally I initialize UIButton like this .. but I don't even know if that's the best place to do this? (You can't do it in layoutSubviews, since it will loop of course.)
class InitializeyButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
common()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
common()
}
func common() {
...
}
}
How to achieve in code ...
system font, weight bold
size 11
kern attribute set to -2
Here is the class you can use to get the desired result:
class InitializeyButton: UIButton {
#IBInspectable var spacing:CGFloat = 0 {
didSet {
updateTitleOfLabel()
}
}
override func setTitle(_ title: String?, for state: UIControl.State) {
let color = super.titleColor(for: state) ?? UIColor.black
let attributedTitle = NSAttributedString(
string: title ?? "",
attributes: [NSAttributedString.Key.kern: spacing,
NSAttributedString.Key.foregroundColor: color,
NSAttributedString.Key.font: UIFont.systemFont(ofSize: self.titleLabel?.font.pointSize ?? 11, weight: .bold) ])
super.setAttributedTitle(attributedTitle, for: state)
}
private func updateTitleOfLabel() {
let states:[UIControl.State] = [.normal, .highlighted, .selected, .disabled]
for state in states {
let currentText = super.title(for: state)
self.setTitle(currentText, for: state)
}
}
}
Copy-paste UIButton for systemFont + kerning:
I've tidied up Jawad's excellent information:
Firstly, at bringup time, you have to create the attributed title:
import UIKit
class SmallChatButton: UIIButton { // (note the extra "I" !!)
override func common() {
super.common()
backgroundColor = .your corporate color
contentEdgeInsets = UIEdgeInsets(top: 7, left: 11, bottom: 7, right: 11)
titles()
}
private func titles() {
let states: [UIControl.State] = [.normal, .highlighted, .selected, .disabled]
for state in states {
let currentText = super.title(for: state)
setTitle(currentText, for: state)
}
}
so to achieve that ..
override func setTitle(_ title: String?, for state: UIControl.State) {
let _f = UIFont.systemFont(ofSize: 10, weight: .heavy)
let attributedTitle = NSAttributedString(
string: title ?? "Click",
attributes: [
NSAttributedString.Key.kern: -0.5,
NSAttributedString.Key.foregroundColor: UIColor.white,
NSAttributedString.Key.font: _f
])
setAttributedTitle(attributedTitle, for: state)
}
override func layoutSubviews() { // example of rounded corners
super.layoutSubviews()
layer.cornerRadius = bounds.height / 2.0
clipsToBounds = true
}
}
Note that a kern of "-0.5" is about what most typographers want for typical "slightly tight type".
It looks good with say all caps, or a slightly bold font, or small type. The Apple measurement system is unlike anything used by typographers, so, you'll just have to vary it until the typographer on your app is satisfied.
What is UIIButton (note the extra "I" !!)
Inevitably in any project you will need a UIButton which has an "I" initializer, so you'll proabbly have:
import UIKit
class UIIButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
common()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
common()
}
func common() {
}
}
(It's quite amazing that in iOS one has to do all of the above to "kern the system font" !)

How can i set dynamic font in swift?

I am using "Automatic adjust font" property of UILabel, It working fine with TextStyles - "Body", "callout", "Headline" etc.
but not works with system font.
Is that "Automatic adjust font" only works with above Textstyles?
extension UILabel {
open override func awakeFromNib() {
super.awakeFromNib()
self.setup()
}
func setup() {
let size = self.font.pointSize*widthFactor
self.font = UIFont.init(name: self.font.fontName, size: size)
if self.attributedText != nil {
let str = self.attributedText
self.attributedText = str
}else{
let str = self.text
self.text = str
}
}
}

Adjust font size of NSMutableAttributedString proportional to UILabel's frame height

In my project, I am using swift 3.0. Right now I am using following class (UILabel subclass) to adjust font size based on UILabel frame height. When UILabel frame change occurs, layoutSubviews recalculates proportional font size.
class Label: UILabel {
// FIXME: - properties
var fontSize: CGFloat = 0
var frameHeight: CGFloat = 0
// FIXME: - proportional font size adjustment
override func layoutSubviews() {
super.layoutSubviews()
font = font.withSize(frame.size.height * (fontSize / frameHeight))
}
}
HOW TO USE:
private let id: Label = {
let label = Label()
label.textAlignment = .left
label.numberOfLines = 1
label.font = UIFont.systemFont(ofSize: 17, weight: .semibold)
label.textColor = UIColor(hex: 0x212121, alpha: 1)
label.fontSize = 17
label.frameHeight = 20
label.clipsToBounds = true
return label
}()
Now I want to show some part of String in UILabel as BOLD TEXT and remaining in REGULAR TEXT. So I have found some help on this thread: Making text bold using attributed string in swift
I am using "Prajeet Shrestha's" extension for NSMutableAttributedString.
// "Prajeet Shrestha's" extension
extension NSMutableAttributedString {
func bold(_ text:String) -> NSMutableAttributedString {
let attrs:[String:AnyObject] = [NSFontAttributeName : UIFont(name: "AvenirNext-Medium", size: 12)!]
let boldString = NSMutableAttributedString(string:"\(text)", attributes:attrs)
self.append(boldString)
return self
}
func normal(_ text:String)->NSMutableAttributedString {
let normal = NSAttributedString(string: text)
self.append(normal)
return self
}
}
But I am not getting how I can change font size of this NSMutableAttributedString, when UILabel frame change occurs?
Any help appeciated.
Try this
Source Looping Through NSAttributedString Attributes to Increase Font SIze
mutableStringObj?.enumerateAttribute(NSFontAttributeName, in: NSRange(location: 0, length: mutableStringObj?.length), options: [], usingBlock: {(_ value: Any, _ range: NSRange, _ stop: Bool) -> Void in
if value {
var oldFont: UIFont? = (value as? UIFont)
var newFont: UIFont? = oldFont?.withSize(CGFloat(oldFont?.pointSize * 2))
res?.removeAttribute(NSFontAttributeName, range: range)
res?.addAttribute(NSFontAttributeName, value: newFont, range: range)
}
})
Finally come up with an answer.
I created seperate custom UILabel subclass as follows:
class AttrLabel: UILabel {
// FIXME: - properties
var fontSize: CGFloat = 0
var frameHeight: CGFloat = 0
// FIXME: - proportional font size adjustment
override func layoutSubviews() {
super.layoutSubviews()
guard let oldAttrText = attributedText else {
return
}
let mutableAttributedText = NSMutableAttributedString(attributedString: oldAttrText)
mutableAttributedText.beginEditing()
mutableAttributedText.enumerateAttribute(NSFontAttributeName, in: NSRange(location: 0, length: mutableAttributedText.length), options: []) { (_ value: Any?, _ range: NSRange, _ stop: UnsafeMutablePointer<ObjCBool>) in
if let attributeFont = value as? UIFont {
let newFont = attributeFont.withSize(self.frame.size.height * (self.fontSize / self.frameHeight))
mutableAttributedText.removeAttribute(NSFontAttributeName, range: range)
mutableAttributedText.addAttribute(NSFontAttributeName, value: newFont, range: range)
}
}
mutableAttributedText.endEditing()
attributedText = mutableAttributedText
}
}
HOW TO USE:
private let id: AttrLabel = {
let label = AttrLabel()
label.textAlignment = .left
label.numberOfLines = 1
label.fontSize = 17
label.frameHeight = 20
label.clipsToBounds = true
return label
}()
SETTING ATTRIBUTED TEXT
let idStr = NSMutableAttributedString()
id.attributedText = idStr.attrStr(text: "BOLD TEXT: ", font: UIFont.systemFont(ofSize: 17, weight: .semibold), textColor: UIColor(hex: 0x212121, alpha: 1)).attrStr(text: "REGULAR WEIGHT TEXT.", font: UIFont.systemFont(ofSize: 17, weight: .regular), textColor: UIColor(hex: 0x212121, alpha: 1))
"Prajeet Shrestha's" extension for NSMutableAttributedString modified by me
extension NSMutableAttributedString {
func attrStr(text: String, font: UIFont, textColor: UIColor) -> NSMutableAttributedString {
let attributes: [String: Any] = [
NSFontAttributeName: font,
NSForegroundColorAttributeName: textColor
]
let string = NSMutableAttributedString(string: text, attributes: attributes)
self.append(string)
return self
}
}
Try Using label property adjustsFontSizeToFitWidth AND minimumScaleFactor like this:
label.adjustsFontSizeToFitWidth = true
label.minimumScaleFactor = 0.2
then you also need to increase number of lines like this any number instead of 10
label.numberOfLines = 10

Multiline UIButton with each line truncated independently

I'm trying to make a multiline button by subclassing UIButton. To avoid drawing two custom UILabel (I'm still pretty new to Swift/Xcode), I'm using attributed strings for the existing UILabel and splitting lines with a new line character, like so:
func prepareAttributedTitle(_ primaryTitle: String = "", _ secondaryTitle: String = "") {
let title = NSMutableAttributedString()
let first = NSAttributedString(string: primaryTitle, attributes: [
NSForegroundColorAttributeName: tintColor,
NSFontAttributeName: UIFont.systemFont(ofSize: UIFont.systemFontSize, weight: UIFontWeightSemibold)
])
let newLine = NSAttributedString(string: "\n")
let second = NSAttributedString(string: secondaryTitle, attributes: [
NSForegroundColorAttributeName: tintColor.withAlphaComponent(0.75),
NSFontAttributeName: UIFont.systemFont(ofSize: UIFont.smallSystemFontSize)
])
title.append(first)
title.append(newLine)
title.append(second)
setAttributedTitle(title, for: .normal)
}
And the result is (sorry, I don't have enough rep to post images):
| This is the long first |
| line |
| Secondary line |
However, I'd like to truncate lines independently, like this:
| This is the long fi... |
| Secondary line |
Is there a way to do this without using two custom UILabels?
Thanks
A single UILabel does not support what you need. You will have to use two single-line labels each set with tail truncation.
I'm answering my own question with what worked for me. Here's my subclass of UIButton, but keep in mind I'm not an experienced developer. There's also some styling and support for the tint color:
import UIKit
#IBDesignable
class FilterButton: UIButton {
let primaryLabel = UILabel()
let secondaryLabel = UILabel()
#IBInspectable var primaryTitle = "" {
didSet {
primaryLabel.text = primaryTitle
}
}
#IBInspectable var secondaryTitle = "" {
didSet {
secondaryLabel.text = secondaryTitle
}
}
// MARK: Initialization
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
override func prepareForInterfaceBuilder() {
primaryTitle = "Primary title"
secondaryTitle = "Secondary title"
commonInit()
}
func commonInit() {
// Force left alignment (FIXME: Use user language direction)
contentHorizontalAlignment = .left
// Set some padding and styling
contentEdgeInsets = UIEdgeInsets(top: 5, left: 10, bottom: 5, right: 10)
layer.cornerRadius = 5
layer.borderWidth = 1
// Hide button original label
titleLabel?.isHidden = true
// Prepare the primary label
primaryLabel.frame = CGRect(x: contentEdgeInsets.left,
y: contentEdgeInsets.top,
width: frame.width - contentEdgeInsets.left - contentEdgeInsets.right,
height: (frame.height - contentEdgeInsets.top - contentEdgeInsets.bottom) / 2)
primaryLabel.font = UIFont.boldSystemFont(ofSize: UIFont.systemFontSize)
primaryLabel.textColor = tintColor
// primaryLabel.backgroundColor = UIColor.green // For debugging
primaryLabel.lineBreakMode = .byTruncatingMiddle // Truncate first line
primaryLabel.autoresizingMask = .flexibleWidth
addSubview(primaryLabel)
// Prepare the secondary label
secondaryLabel.frame = CGRect(x: contentEdgeInsets.left,
y: contentEdgeInsets.top + primaryLabel.frame.height,
width: frame.width - contentEdgeInsets.left - contentEdgeInsets.right,
height: (frame.height - contentEdgeInsets.top - contentEdgeInsets.bottom) / 2)
secondaryLabel.font = UIFont.systemFont(ofSize: UIFont.smallSystemFontSize)
secondaryLabel.textColor = tintColor.withAlphaComponent(0.75)
// secondaryLabel.backgroundColor = UIColor.yellow // For debugging
secondaryLabel.lineBreakMode = .byTruncatingMiddle // Truncate second line
secondaryLabel.autoresizingMask = .flexibleWidth
addSubview(secondaryLabel)
primaryLabel.text = primaryTitle
secondaryLabel.text = secondaryTitle
}
// Support tint color
override func tintColorDidChange() {
super.tintColorDidChange()
layer.borderColor = tintColor.cgColor
layer.backgroundColor = tintColor.withAlphaComponent(0.05).cgColor
primaryLabel.textColor = tintColor
secondaryLabel.textColor = tintColor.withAlphaComponent(0.75)
}
}

Swift - UIButton with two lines of text

I was wondering if it is possible to create a UIButton with two lines of text. I need each line to have a different font size. The first line will be 17 point and the second will be 11 point. I've tried messing with putting two labels inside of a UIButton, but I can't get them to stay inside the bounds of the button.
I'm attempting to do all of this in the ui builder, and not programmatically.
Thanks
There are two questions.
I was wondering if it is possible to create a UIButton with two lines
of text
This is possible through using the storyboard or programmatically.
Storyboard:
Change the 'Line Break Mode' to Character Wrap or Word Wrap and use Alt/Option + Enter key to enter a new line in the UIButton's Title field.
Programmatically:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
btnTwoLine?.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping;
}
I need each line to have a different font size
1
The worst case is, you can use a custom UIButton class and add two labels within it.
The better way is, make use of NSMutableAttributedString. Note that,this can be achieved through only programmatically.
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: [])
}
Older 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)
}
Output
I was looking for nearly the same topic, except that I don't need two different font sizes. In case someone is looking for a simple solution:
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)
I have notice an issue in most of the solutions which is while making line break mode to "Character Wrap" the second line will be left aligned to the first line
To make all the lines centered.
just change the title From Plain to Attributed and then you can make each line centered
change line break to character wrap , select your button and in attribute inspector go to line break and change it to character wrap
SWIFT 3 Syntax
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)
I have fixed this and my solution it was only in the Storyboard.
Changes:
It added in Identity Inspector -> User Defined Runtime Attributes (these KeyPaths):
numberOfLines = 2
titleLabel.textAlignment = 1
User Defined Runtime Attributes
I added this in attributes inspector:
line break = word wrap
Word wrap
You need to do some of this in code. you can't set 2 different fonts in IB. In addition to changing the line break mode to character wrap, you need something like this to set the title,
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)
}
New with Xcode 13 (iOS 15)
Starting with Xcode 13, the button's title and subtitle may have their attributes set separately.
Using Storyboard:
In the Attribute Inspector for the button, select "Attributed" by Title. Then change font size of the title and the subtitle.
Or Programmatically:
// Create Title
let titleSettings = AttributeContainer.font( UIFont(name: "HelveticaNeue-Italic", size: 17)! )
yourButton.configuration?.attributedTitle = AttributedString("Button's Title", attributes: titleSettings)
// Create Subtitle
let subtitleSettings = AttributeContainer.font( UIFont(name: "HelveticaNeue-Italic", size: 11)! )
yourButton.configuration?.attributedSubtitle = AttributedString("Button's Subtitle", attributes: subtitleSettings)
One way to do it is with labels, I guess. I did this, and it seems to work ok. I could create this as a UIButton and then expose the labels, I guess. I don't know if this makes any sense.
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)
The suggested solutions unfortunately did not work out for me when I wanted to have a mutliline button inside a CollectionView. Then a colleague showed me a workaround which I wanted to share in case someone has the same problem - hope this helps! Create a class which inherits from UIControl and extend it with a label, which will then behave similar like a button.
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")
}
}
my way:
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)
}

Resources