Search code examples
iosobjective-cfontsinterface-builderuilabel

iOS/Objective-C UILabel text kerning


I was searching how to increase character spacing in UILabels to make my UI Design implementations more attractive. I found following answer, which tells it allows to adjust the Text Kerning, and it's written in Swift.

But what I needed is an Objective-C Solution. So I tried to convert the following code snippet:

import UIKit
@IBDesignable
class KerningLabel: UILabel {
    @IBInspectable var kerning:CGFloat = 0.0{
        didSet{
            if ((self.attributedText?.length) != nil)
            {
                let attribString = NSMutableAttributedString(attributedString: self.attributedText!)
                attribString.addAttributes([NSKernAttributeName:kerning], range:NSMakeRange(0, self.attributedText!.length))
                self.attributedText = attribString
            }
        }
    }
}

to following in Objective-C:

KerningLabel.h:

#import <UIKit/UIKit.h>
IB_DESIGNABLE
@interface KerningLabel : UILabel
@property (nonatomic) IBInspectable CGFloat kerning;
@end

KerningLabel.m:

#import "KerningLabel.h"

@implementation KerningLabel
@synthesize kerning;
- (void) setAttributedText:(NSAttributedString *)attributedText {
    if ([self.attributedText length] > 0) {
        NSMutableAttributedString *muAttrString = [[NSMutableAttributedString alloc] initWithAttributedString:self.attributedText];
        [muAttrString addAttribute:NSKernAttributeName value:@(self.kerning) range:NSMakeRange(0, [self.attributedText length])];
        self.attributedText = muAttrString;
    }
}
@end

And it gives the following Attribute in XCode IB to adjust the kerning:

enter image description here

But it really doesn't seem to be taking effect on the UI when the App is running and also in the Interface Builder the text disappears.

What have I done wrong?


Solution

  • You want to update your attributedText every time kerning is updated. So, your .h should look like:

    IB_DESIGNABLE
    @interface KerningLabel : UILabel
    
    @property (nonatomic) IBInspectable CGFloat kerning;
    
    @end
    

    and your .m :

    @implementation KerningLabel
    
    - (void)setKerning:(CGFloat)kerning
    {
        _kerning = kerning;
    
        if(self.attributedText)
        {
            NSMutableAttributedString *attribString = [[NSMutableAttributedString alloc]initWithAttributedString:self.attributedText];
            [attribString addAttribute:NSKernAttributeName value:@(kerning) range:NSMakeRange(0, self.attributedText.length)];
            self.attributedText = attribString;
         }
    }
    
    @end