Ios 将UITextViews文本替换为属性化字符串
我有一个Ios 将UITextViews文本替换为属性化字符串,ios,uitextview,core-text,nsattributedstring,Ios,Uitextview,Core Text,Nsattributedstring,我有一个UITextView,当用户在其中输入文本时,我想动态格式化文本。类似于语法突出显示 为此,我想使用UITextView 除了一个问题外,一切正常:我从文本视图中获取文本,并从中生成一个NSAttributedString。我对该属性字符串进行了一些编辑,并将其设置回textView.attributedText 每次用户输入时都会发生这种情况。因此,在编辑属性文本之前,我必须记住selectedtextange,然后将其设置回原来的位置,以便用户可以继续在以前键入的位置键入。唯一的问题
UITextView
,当用户在其中输入文本时,我想动态格式化文本。类似于语法突出显示
为此,我想使用UITextView
除了一个问题外,一切正常:我从文本视图中获取文本,并从中生成一个NSAttributedString
。我对该属性字符串进行了一些编辑,并将其设置回textView.attributedText
每次用户输入时都会发生这种情况。因此,在编辑属性文本之前,我必须记住selectedtextange
,然后将其设置回原来的位置,以便用户可以继续在以前键入的位置键入。唯一的问题是,一旦文本足够长,需要滚动时,UITextView
现在将开始滚动到顶部(如果我缓慢键入)
以下是一些示例代码:
- (void)formatTextInTextView:(UITextView *)textView
{
NSRange selectedRange = textView.selectedRange;
NSString *text = textView.text;
// This will give me an attributedString with the base text-style
NSMutableAttributedString *attributedString = [self attributedStringFromString:text];
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"#(\\w+)" options:0 error:&error];
NSArray *matches = [regex matchesInString:text
options:0
range:NSMakeRange(0, text.length)];
for (NSTextCheckingResult *match in matches)
{
NSRange matchRange = [match rangeAtIndex:0];
[attributedString addAttribute:NSForegroundColorAttributeName
value:[UIColor redColor]
range:matchRange];
}
textView.attributedText = attributedString;
textView.selectedRange = selectedRange;
}
有没有不直接使用CoreText的解决方案?我喜欢UITextView
s选择文本等功能。我不确定这是否是正确的解决方案,但它确实有效。
只需在格式化文本前禁用滚动,并在格式化后启用即可
- (void)formatTextInTextView:(UITextView *)textView
{
textView.scrollEnabled = NO;
NSRange selectedRange = textView.selectedRange;
NSString *text = textView.text;
// This will give me an attributedString with the base text-style
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text];
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"#(\\w+)" options:0 error:&error];
NSArray *matches = [regex matchesInString:text
options:0
range:NSMakeRange(0, text.length)];
for (NSTextCheckingResult *match in matches)
{
NSRange matchRange = [match rangeAtIndex:0];
[attributedString addAttribute:NSForegroundColorAttributeName
value:[UIColor redColor]
range:matchRange];
}
textView.attributedText = attributedString;
textView.selectedRange = selectedRange;
textView.scrollEnabled = YES;
}
Swift 2.0:
let myDisplayTxt:String = "Test String"
let string: NSMutableAttributedString = NSMutableAttributedString(string: self.myDisplayTxt)
string.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: NSMakeRange(0, 5))
string.addAttribute(String(kCTForegroundColorAttributeName), value: UIColor.redColor().CGColor as AnyObject, range: NSMakeRange(0, 5))
self.sampleTextView.attributedText = string
我自己使用了谢尔盖的答案并将其移植到Swift 2:
func formatTextInTextView(textView: UITextView) {
textView.scrollEnabled = false
let selectedRange = textView.selectedRange
let text = textView.text
// This will give me an attributedString with the base text-style
let attributedString = NSMutableAttributedString(string: text)
let regex = try? NSRegularExpression(pattern: "#(\\w+)", options: [])
let matches = regex!.matchesInString(text, options: [], range: NSMakeRange(0, text.characters.count))
for match in matches {
let matchRange = match.rangeAtIndex(0)
attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: matchRange)
}
textView.attributedText = attributedString
textView.selectedRange = selectedRange
textView.scrollEnabled = true
}
在Swift 4中:
func createAttributedText() {
let stringText = "Test String"
let stringCount = stringText.count
let string: NSMutableAttributedString = NSMutableAttributedString(string: stringText)
string.addAttribute(NSForegroundColorAttributeName, value: UIColor.red, range: NSMakeRange(0, stringCount))
self.textView.attributedText = string
}
@NANNAV感谢您通过编辑帖子来改进SO。然而,对于你随意大胆的强调似乎。它只会引入噪音,实际上可能被认为是有害的。谢谢你的回答!!!:)与此同时,我找到了另一个解决方案。。。我只是将UITextView子类化并重写了“scrollRectToVisible:animated:”并让它调用super而不需要动画。。。您的解决方案似乎更流畅:)再次感谢!谢谢你的回答。它给了我一个解决问题的方法。当我调用此方法时,Swift 5+的更新:NSForegroundColorAttributeName
应该替换为NSAttributeString.Key.foregroundColor
?事实上,我想像你的代码一样,但作为链接。你能分享那个代码吗。