在iOS UITextView中进行确认

对于显然是一个“错误”,UITextView似乎不像其他UIKit元素那样支持字距调整。 有没有解决方法来克服工作?

清楚的是,我正在讨论在字体文件中定义的字符对之间的间距,而不是所有字符之间的总体间距。 在NSAttributedString使用NSKernAttributeName将调整所有字符之间的间距,但内置的字符对仍然不起作用。

例如:

在这里输入图像说明

有没有解决这个问题的解决方法?

我发现一个简单的解决方法是将CSS样式添加到启用字距调整的UITextView。 如果我使用未公开的方法setContentToHTMLString:我可以将CSS注入到文本视图中的秘密web视图。

 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?

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

使用webview和contenteditable属性。 这是不理想的,因为webview做了一堆额外的东西,例如input辅助视图,不容易被隐藏。

使用核心文本手动子类化UITextView并呈现文本。 这比我希望的更复杂,因为所有select的东西都​​需要重新configuration。 由于UITextViewUITextPositionUITextRange的私有子类,这是一个巨大的痛苦,如果不是完全不可能的屁股。

你是对的,你的应用程序可能会被拒绝使用@select器@selector(setContentToHTMLString:) 。 但是,您可以使用一个简单的技巧来dynamic构造select器,以便在validation期间不会检测到它。

 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 } 

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

通常不build议使用私有API,但是在这种情况下,我认为使用一个小小的黑客vs用CoreText重写UITextView是完全合理的。

尝试这个:

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

它适用于我的testing。 当然,我还没有在app store尝试过。

在研究了这一点后,我发现缺lessKerning的原因是UITextView内部使用了默认closuresKerning的UIWebDocumentView。

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

不幸的是,没有任何制裁的方法来启用Kerning,我绝对build议不要使用伪装的select器使用黑客。

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

在这里,我认为当通过setAttributedText在UITextView上设置文本时,我们开发人员期望Kerning默认打开,因为这是通过CoreText来最接近地匹配输出的。

你看看这里: https : //github.com/AliSoftware/OHAttributedLabel ? 看看这个项目,看起来应用程序商店中有几个应用程序正在使用标记(由此类提供)。 也许你可以使用这个类,或从中收集一些实现的想法。 也许你的应用程序将通过调整。

在iOS6中, UITextView有一个新的attributesText attributedText ,你可以为它分配一个NSAttributedString 。 我还没有尝试过,但是如果你设置了文本视图的这个属性而不是text属性,那么看看你是否得到了string会很有趣。 而且它具有作为公共接口的附加好处。

没有必要诉诸私人的方法。 通过订阅UITextFieldTextDidChangeNotification通知,每当文本更改时,都可以通过dynamic更改文本字段的attributedText文本attributedText轻松地伪造它:

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