在iOS UITextView中进行Kerning

Ant*_*tox 23 css objective-c uitextview kerning ios

对于显然是'bug',UITextView似乎不像其他UIKit Elements那样支持字距调整.是否有解决方法来让角色工作?

为了清楚起见,我在谈论字体文件中定义的字符对之间的间距,而不是所有字符之间的一般间距.使用NSAttributedStringwith NSKernAttributeName将调整所有字符之间的间距,但内置字符对仍然不起作用.

例如:

在此输入图像描述

有解决方法可以解决这个问题吗?

我发现的一个简单的解决方法是向UITextView添加css样式以启用字距调整.如果我使用未记录的方法,setContentToHTMLString:我可以将css注入文本视图中的秘密webview.

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];
Run Code Online (Sandbox Code Playgroud)

这可以立即解决问题; 但是,这似乎很可能会让应用程序被拒绝.有没有一种安全的方法可以将某些css隐藏到文本视图中?

我尝试过的其他解决方法包括:

使用webview和contenteditable属性.这并不理想,因为webview会阻碍一些额外的东西,例如输入附件视图,这些视图无法轻易隐藏.

UITextView使用核心文本手动子类化和渲染文本.这比我希望的更复杂,因为所有选择的东西也需要重新配置.因为它UITextView的私人子类,如果不是完全不可能的话UITextPosition,UITextRange这是一个巨大的痛苦.

0xc*_*ced 36

你是对的,你的应用可能会被拒绝使用@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
}
Run Code Online (Sandbox Code Playgroud)

通过将调用包装在@ try/@ catch块中,您还可以确保setContentToHTMLString:在将来的iOS版本中删除该方法时,您的应用程序不会崩溃.

通常不推荐使用私有API,但在这种情况下,我认为使用小型hack与使用CoreText重写UITextView完全有意义.

  • 我有使用这个技巧的应用程序 - 但我使用了--respondsToSelector :,而不是@ try/@ catch (2认同)