ios 如何在 iPhone UILabel 中设置字距调整

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7370013/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:27:07  来源:igfitidea点击:

How to set kerning in iPhone UILabel

ioscocoa-touchuilabelkerning

提问by kz00011

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?

我正在开发一个 iPhone 应用程序,我想在 UILabel 中设置字距调整。我写的代码(可能在 周围kCTKernAttributeName)似乎有错误。我该如何解决这个问题?

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];

回答by DBD

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

对于 2013 年 11 月,只是为了扩展这个很好的答案,这里有一些完全典型的代码。通常你也会设置字体。请注意注释中使用普通旧 .text 的老式方式。希望它可以帮助某人

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];

回答by Andrew Schreiber

Before:

前:

before

前

After:

后:

cafter

卡夫特

Here's a Swift 3 extension that let's you set a UILabel's kerning via codeor storyboard:

这是一个 Swift 3 扩展,可让您通过代码故事板设置 UILabel 的字距调整:

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
        }
    }
}

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.8tends to work well in practice.

该演示使用 3.0 字距调整,但我发现0.1 - 0.8在实践中往往效果很好。

回答by Jeff Hay

Taking DBD's answer, I made a category on UILabel which allows setting the kerning if running on iOS6+ with graceful fall back to just setting text on previous iOS versions. Might be of help to others...

根据 DBD 的回答,我在 UILabel 上创建了一个类别,它允许在 iOS6+ 上运行时设置字距调整,并优雅地回退到仅在以前的 iOS 版本上设置文本。可能对其他人有帮助...

UILabel+TextKerning.h

UILabel+TextKerning.h

#import <UIKit/UIKit.h>

@interface UILabel (TextKerning)

/**
 * Set the label's text to the given string, using the given kerning value if able.
 * (i.e., if running on iOS 6.0+). The kerning value specifies the number of points
 * by which to adjust spacing between characters (positive values increase spacing,
 * negative values decrease spacing, a value of 0 is default)
 **/
- (void) setText:(NSString *)text withKerning:(CGFloat)kerning;

/**
 * Set the kerning value of the currently-set text.  The kerning value specifies the number of points
 * by which to adjust spacing between characters (positive values increase spacing,
 * negative values decrease spacing, a value of 0 is default)
 **/
- (void) setKerning:(CGFloat)kerning;

@end

UILabel+TextKerning.m

UILabel+TextKerning.m

#import "UILabel+TextKerning.h"

@implementation UILabel (TextKerning)

-(void) setText:(NSString *)text withKerning:(CGFloat)kerning
{
    if ([self respondsToSelector:@selector(setAttributedText:)])
    {
        NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text];
        [attributedString addAttribute:NSKernAttributeName
                                 value:[NSNumber numberWithFloat:kerning]
                                 range:NSMakeRange(0, [text length])];
        [self setAttributedText:attributedString];
    }
    else
        [self setText:text];
}

-(void) setKerning:(CGFloat)kerning
{
    [self setText:self.text withKerning:kerning];
}

回答by calimarkus

Just to be up-to-date here, iOS 6 introduced attributedText for UILabeland UITextView!

只是为了保持最新状态,iOS 6 为UILabel和引入了属性文本UITextView

UILabel reference:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UILabel_Class/Reference/UILabel.html#//apple_ref/occ/instp/UILabel/attributedText

UILabel 参考:http:
//developer.apple.com/library/ios/#documentation/uikit/reference/UILabel_Class/Reference/UILabel.html#//apple_ref/occ/instp/UILabel/attributedText

回答by CodeOverRide

Just do this in Swift:

只需在 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()

回答by Arben Pnishi

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.

使用 IBDesignables 和 IBInspectables 的示例,您可以在其中管理仅通过故事板设置字距调整值。我发现它非常实用,我想与您分享。

UILabelKerning.h

UILabelKerning.h

#import <UIKit/UIKit.h>

IB_DESIGNABLE

@interface UILabelKerning : UILabel
@property (assign, nonatomic) IBInspectable int kerning;
@end

UILabelKerning.m

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

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明

回答by Eoin

As far as I am aware, UILabelwill not render the characteristics of NSAttributedString. There are a couple of nice open source solutions. I recently used TTTAttributedLabelas a swap in replacement for UILabel that accepts NSAttributedString.

据我所知,UILabel不会渲染NSAttributedString. 有几个不错的开源解决方案。我最近使用TTTAttributedLabel作为替代接受 NSAttributedString 的 UILabel 的交换。

DTCoreText(former NSAttributedString+HTML) is also getting a bit of buzz lately.

DTCoreText(以前的 NSAttributedString+HTML)最近也引起了一些轰动。

回答by Rashid Latif

Swift 4 and 5

斯威夫特 4 和 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)
    }
 ]

回答by rab_w

In Swift 2.0...

在 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:

现在,只需将您的 UILabel 设置为属性文本:

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

显然,我添加了一堆您可能不需要的参数。试一试——随意重写这个方法——我在一堆不同的答案中寻找这个,所以我想我会发布整个扩展,以防它帮助那里的人...... -rab