How to set kerning in iPhone UILabel

2019-01-07 09:28发布

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 might I approach fixing this?

NSMutableAttributedString *attStr;   
NSString *str = @"aaaaaaa";    
CFStringRef kern = kCTKernAttributeName;        
NSNumber *num = [NSNumber numberWithFloat: 2.0f];    
NSDictionary *attributesDict = [NSDictionary dictionaryWithObject:num 
forKey:(NSString*)kern];        
[attStr initWithString:str attributes:attributesDict];      
CGRect frame1 = CGRectMake(0, 0, 100, 40);    
UILabel *label1 = [[UILabel alloc] initWithFrame:frame1];    
label1.text = attStr    
[self.view addSubview:label1];

8条回答
我只想做你的唯一
2楼-- · 2019-01-07 09:52

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.

查看更多
劫难
3楼-- · 2019-01-07 09:59

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

查看更多
疯言疯语
4楼-- · 2019-01-07 10:01

Before:

before

After:

cafter

Here's a Swift 2 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 ?? "").characters.count)
            guard let kern = attributedText?.attribute(NSKernAttributeName, 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(NSKernAttributeName, value: NSNumber(value: newValue), range: range)
            self.attributedText = attText
        }
    }
}

Demo usage:

myLabel.kerning = 3.0

or

enter image description here

The demo uses 3.0 kerning for drama, but I've found 0.1 - 0.8 tends to work well in practice.

查看更多
爱情/是我丢掉的垃圾
5楼-- · 2019-01-07 10:05

Old question, but you can do it now (easily).

NSMutableAttributedString *attributedString;
attributedString = [[NSMutableAttributedString alloc] initWithString:@"Please get wider"];
[attributedString addAttribute:NSKernAttributeName value:@5 range:NSMakeRange(10, 5)];
[self.label setAttributedText:attributedString];

enter image description here

For Nov 2013, Just to expand on this great answer, here's some totally typical code. Usually you'd set the font as well. Note in the comments the old-fashioned way using ordinary old .text. Hope it helps someone

NSString *yourText = @"whatever";

UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(0,0,0,0)];

// simple approach with no tracking...
// label.text = yourText;
// [label setFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:24]];

NSMutableAttributedString *attributedString;

attributedString = [[NSMutableAttributedString alloc] initWithString:yourText];

[attributedString addAttribute:NSKernAttributeName
                         value:[NSNumber numberWithFloat:2.0]
                         range:NSMakeRange(0, [yourText length])];

[attributedString addAttribute:NSFontAttributeName
                         value:[UIFont fontWithName:@"HelveticaNeue-Light" size:24]
                         range:NSMakeRange(0, [yourText length])];

label.attributedText = attributedString;

label.textColor = [UIColor blackColor];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = NSTextAlignmentCenter;

[label sizeToFit];
查看更多
欢心
6楼-- · 2019-01-07 10:09

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

查看更多
迷人小祖宗
7楼-- · 2019-01-07 10:13

Just do this in Swift:

    let myTitle = "my title"
    let titleLabel = UILabel()
    let attributes: NSDictionary = [
        NSFontAttributeName:UIFont(name: "HelveticaNeue-Light", size: 20),
        NSForegroundColorAttributeName:UIColor.whiteColor(),
        NSKernAttributeName:CGFloat(2.0)
    ]
    let attributedTitle = NSAttributedString(string: myTitle, attributes: attributes as? [String : AnyObject])

    titleLabel.attributedText = attributedTitle
    titleLabel.sizeToFit()
查看更多
登录 后发表回答