I am developing an iPhone app, and I want to set kerning in UILabel. The code I\'ve written (possibly around kCTKernAttributeName
) seems to be in error. How mig
Here's a Swift 3 extension that let's you set a UILabel's kerning via code or storyboard:
extension UILabel {
@IBInspectable var kerning: Float {
get {
var range = NSMakeRange(0, (text ?? "").count)
guard let kern = attributedText?.attribute(NSAttributedStringKey.kern, at: 0, effectiveRange: &range),
let value = kern as? NSNumber
else {
return 0
}
return value.floatValue
}
set {
var attText:NSMutableAttributedString
if let attributedText = attributedText {
attText = NSMutableAttributedString(attributedString: attributedText)
} else if let text = text {
attText = NSMutableAttributedString(string: text)
} else {
attText = NSMutableAttributedString(string: "")
}
let range = NSMakeRange(0, attText.length)
attText.addAttribute(NSAttributedStringKey.kern, value: NSNumber(value: newValue), range: range)
self.attributedText = attText
}
}
}
myLabel.kerning = 3.0
or
The demo uses 3.0 kerning for drama, but I've found 0.1 - 0.8 tends to work well in practice.
Swift 4 and 5
extension NSAttributedString {
/// Returns a new instance of NSAttributedString with same contents and attributes with kerning added.
/// - Parameter kerning: a kerning you want to assign to the text.
/// - Returns: a new instance of NSAttributedString with given kerning.
func withKerning(_ kerning: CGFloat) -> NSAttributedString {
let attributedString = NSMutableAttributedString(attributedString: self)
attributedString.addAttributes([.kern: kerning],
range: NSRange(location: 0, length: string.count))
return NSAttributedString(attributedString: attributedString)
}
]
In Swift 2.0...
Add an extension:
extension UIView {
func attributes(font: String, color: UIColor, fontSize: CGFloat, kern: Double) -> [String: NSObject] {
let attribute = [
NSForegroundColorAttributeName: color,
NSKernAttributeName: kern,
NSFontAttributeName : UIFont(name: font, size: fontSize)!
]
return attribute
}
}
Now, just set your UILabel as attributedText:
self.label.attributedText = NSMutableAttributedString(string: "SwiftExample", attributes: attributes("SourceSans-Regular", color: UIColor.whiteColor(), fontSize: 20, kern: 2.0))
Obviously, I added a bunch of parameters that you may not need. Play around -- feel free to rewrite the method -- I was looking for this on a bunch of different answers so figured I'd post the whole extension in case it helps someone out there... -rab
Just to be up-to-date here, iOS 6 introduced attributedText for UILabel
and UITextView
!
UILabel reference:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UILabel_Class/Reference/UILabel.html#//apple_ref/occ/instp/UILabel/attributedText
As far as I am aware, UILabel
will not render the characteristics of NSAttributedString
. There are a couple of nice open source solutions. I recently used TTTAttributedLabel as a swap in replacement for UILabel that accepts NSAttributedString.
DTCoreText (former NSAttributedString+HTML) is also getting a bit of buzz lately.
An example using IBDesignables and IBInspectables where you can manage to set the kerning value through storyboard only. I found it very practical and I thought to share it with you.
UILabelKerning.h
#import <UIKit/UIKit.h>
IB_DESIGNABLE
@interface UILabelKerning : UILabel
@property (assign, nonatomic) IBInspectable int kerning;
@end
UILabelKerning.m
#import "UILabelKerning.h"
@implementation UILabelKerning
-(void)awakeFromNib {
[self setTheAttributes];
}
- (id)initWithCoder:(NSCoder*)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self)
{
// Initialization code
}
return self;
}
-(void)setTheAttributes{
NSMutableAttributedString *attributedString =[[NSMutableAttributedString alloc] initWithAttributedString:self.attributedText];
[attributedString addAttribute:NSKernAttributeName
value:[NSNumber numberWithFloat:self.kerning]
range:NSMakeRange(0, [self.text length])];
[self setAttributedText:attributedString];
}
@end