-->

字距iOS中的UITextView(Kerning in iOS UITextView)

2019-07-03 13:54发布

对于什么显然是一个“错误”,UITextView的似乎不支持字距像其他的UIKit元素。 有一种解决方法,以获取字距工作?

需要明确的是,我说的是在对字符之间的间距字体文件中定义的,不是所有的字符之间的间距一般。 使用NSAttributedStringNSKernAttributeName将调整所有字符之间的间距,但内置的字符对仍然不工作。

例如:

有一种解决方法来解决这个问题?

一个简单的解决方法我发现是CSS样式添加到启用字距的UITextView的。 如果我使用无证方法setContentToHTMLString:我可以注入的CSS文本视图中的秘密网页流量。

NSString *css = @"*{text-rendering: optimizeLegibility;}";
NSString *html = [NSString stringWithFormat:@"<html><head><style>%@</style></head><body>Your HTML Text</body></html>", css];
[textView performSelector:@selector(setContentToHTMLString:) withObject:html];

这立即解决了这个问题; 然而,这似乎很可能这将让该应用程序被拒绝。 有没有偷偷一些CSS到文本视图以安全的方式?

我已经试验过其他解决方法包括:

使用网页视图和CONTENTEDITABLE财产。 因为网页流量做了一堆额外的东西,得到的方式,例如不能轻易地隐藏在输入附件视图这是不理想的。

子类一UITextView和具有核心文本手动绘制文本。 这比我所希望的,因为所有的选择的东西需要重新配置以及更加复杂。 由于UITextView的私有子类UITextPositionUITextRange这是在屁股如果不是完全不可能一个巨大的痛苦。

Answer 1:

你是正确的,你的应用程序可能会通过使用被拒绝@selector(setContentToHTMLString:) 。 但是,您可以使用一个简单的技巧动态构造的选择,这样就不会在验证过程中被检测到。

NSString *css = @"*{text-rendering: optimizeLegibility;}";
NSString *html = [NSString stringWithFormat:@"<html><head><style>%@</style></head><body>Your HTML Text</body></html>", css];
@try {
    SEL setContentToHTMLString = NSSelectorFromString([@[@"set", @"Content", @"To", @"HTML", @"String", @":"] componentsJoinedByString:@""]);
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
    [textView performSelector:setContentToHTMLString withObject:html];
    #pragma clang diagnostic pop
}
@catch (NSException *exception) {
    // html+css could not be applied to text view, so no kerning
}

通过包装内的呼叫尝试@ / @ catch块,你也保证,如果您的应用程序不会崩溃setContentToHTMLString:方法是在iOS的未来版本中删除。

一般不建议使用专用的API,但在这种情况下,我认为这完全是有道理的使用一个小黑客与VS重写CoreText UITextView的。



Answer 2:

研究这个有点后,我发现,失踪的字距原因是UITextView的内部使用具有字距关闭默认情况下,UIWebDocumentView。

有关的UITextView的内部运作的一些相关信息: http://www.cocoanetics.com/2012/12/uitextview-caught-with-trousers-down/

不幸的是没有认可的方法来启用字距,我肯定会建议不要使用黑客利用伪装的选择。

这里是我的雷达,我建议你欺骗它: http://www.cocoanetics.com/2012/12/radar-uitextview-ignores-font-kerning/

在此笔者认为,通过setAttributedText上的UITextView设置文本时,我们开发商期待字距在默认情况下是对,因为这是它是如何将最匹配的渲染通过CoreText文本的输出。



Answer 3:

试试这个:

[textView_ setValue:@"hello, <b>world</b>" forKey:@"contentToHTMLString"];

它工作在我的测试。 我没有在过程中的应用程序商店试了一下。



Answer 4:

你在这里拍一看: https://github.com/AliSoftware/OHAttributedLabel ? 望着这个项目,它似乎有在几个应用程序应用商店所使用的标记(此类提供)。 也许你既可以使用这个类或它搜集了一些实现想法。 也许你的应用程序按原样将通过审核。



Answer 5:

随着iOS6的, UITextView有一个新的属性attributedText ,您可以向其中分配NSAttributedString 。 我还没有尝试过,但它会是有趣的,看看你得到的,如果你设置你的文字鉴于此属性,而不是你是后字距text属性。 它具有作为公共接口的好处。



Answer 6:

有没有必要求助于私有方法。 您可以轻松地伪造它通过动态地改变attributedText每次通过订阅文本更改文本字段的属性UITextFieldTextDidChangeNotification通知:

- (void)viewDidLoad {
    // your regular stuff goes here
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChangeNotification:) name:UITextFieldTextDidChangeNotification object:nil];
}


- (void)textDidChangeNotification:(NSNotification *)notification {
    // you can of course specify other attributes here, such as font and text color
    CGFloat kerning = -3.; // change accordingly to your desired value
    NSDictionary *attributes = @{
                                 NSKernAttributeName: @(kerning),
                                 };
    UITextField *textField = [notification object];
    textField.attributedText = [[NSAttributedString alloc] initWithString:textField.text attributes:attributes];
}


文章来源: Kerning in iOS UITextView