How to change letter spacing of UIButton in Swift?
Swift 4
extension UIButton{
func addTextSpacing(_ letterSpacing: CGFloat){
let attributedString = NSMutableAttributedString(string: (self.titleLabel?.text!)!)
attributedString.addAttribute(NSAttributedString.Key.kern, value: letterSpacing, range: NSRange(location: 0, length: (self.titleLabel?.text!.count)!))
self.setAttributedTitle(attributedString, for: .normal)
}
}
// Usage: button.addTextSpacing(5.0)
Not a full answer, but a GOTCHA, and a FIX.
GOTCHA: applying character spacing also adds the space to the END of the text. This misfeature/bug means that center-aligned text will appear incorrectly.
FIX: when creating a Range for the attributed text, subtract 1 from the text.count value (thus ignoring the last character in the string for spacing purposes.)
e.g. incorrect centering due to extra space:
fixed:
[edited]
On a related note, if you are using EdgeInsets to impose padding around the text, your UIButton
subclass will need to override intrinsicContentsSize:
override open var intrinsicContentSize: CGSize {
let size = super.intrinsicContentSize
let insets = self.titleEdgeInsets
let width = size.width + insets.left + insets.right
let height = size.height + insets.top + insets.bottom
return CGSize(width: width, height: height)
}
- Make the
NSAttributedString
like in the question you linked - Call
setAttributedTitle(_ ,forState:)
on yourUIButton
Try this (untested):
let title = agreementButton.titleForState(.Normal)
let attributedTitle = NSAttributedString(string: title, attributes: [NSKernAttributeName: 1.0])
agreementButton.setAttributedTitle(attributedTitle, forState: .Normal)
Swift 3.0
extension UIButton{
func addTextSpacing(spacing: CGFloat){
let attributedString = NSMutableAttributedString(string: (self.titleLabel?.text!)!)
attributedString.addAttribute(NSKernAttributeName, value: spacing, range: NSRange(location: 0, length: (self.titleLabel?.text!.characters.count)!))
self.setAttributedTitle(attributedString, for: .normal)
}
}
btnRegister.addTextSpacing(spacing: 4.5)
extension UILabel{
func addTextSpacing(spacing: CGFloat){
let attributedString = NSMutableAttributedString(string: self.text!)
attributedString.addAttribute(NSKernAttributeName, value: spacing, range: NSRange(location: 0, length: self.text!.characters.count))
self.attributedText = attributedString
}
}
lblOne.addTextSpacing(spacing: 4.5)
extension UITextField{
func addPlaceholderSpacing(spacing: CGFloat){
let attributedString = NSMutableAttributedString(string: self.placeholder!)
attributedString.addAttribute(NSKernAttributeName, value: spacing, range: NSRange(location: 0, length: self.placeholder!.characters.count))
self.attributedPlaceholder = attributedString
}
}
txtUserName.addPlaceholderSpacing(spacing: 4.5)
extension UINavigationItem{
func addSpacing(spacing: CGFloat){
let attributedString = NSMutableAttributedString(string: self.title!)
attributedString.addAttribute(NSKernAttributeName, value: spacing, range: NSRange(location: 0, length: self.title!.characters.count))
let label = UILabel()
label.textColor = UIColor.black
label.font = UIFont.systemFont(ofSize: 15, weight: UIFontWeightBold)
label.attributedText = attributedString
label.sizeToFit()
self.titleView = label
}
}
navigationItem.addSpacing(spacing: 2.5)