在我的UITextView中使用NSMutableAttributedString但现在用户无法编辑文本[剪切,复制,删除]

时间:2014-07-17 13:58:21

标签: ios objective-c nsmutableattributedstring

使用NSMutableAttributedStringUITextField中的字符串着色,但用户无法剪切,复制或删除字符串。例如,使用下面的代码,如果我键入“blue red @green”然后尝试删除蓝色或剪切蓝色,当我尝试将光标移动到UITextfield中的最后一个字母?

有什么建议吗?

- (void)colorText {
NSMutableAttributedString * string = [[NSMutableAttributedString alloc]initWithString:self.thing.text];

NSArray *words=[self.thing.text componentsSeparatedByString:@" "];

for (NSString *word in words) {
    if([word isEqualToString:@""]) {continue;};
    if ([word hasPrefix:@"@"]) {
        NSRange range=[self.thing.text rangeOfString:word];
        [string addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:range];
    } else {
        NSRange range=[self.thing.text rangeOfString:word];
        [string addAttribute:NSForegroundColorAttributeName value:[UIColor darkGrayColor] range:range];
    }
}
[self.thing setAttributedText:string];
}

1 个答案:

答案 0 :(得分:1)

问题在于您每次都要设置字符串的文本,这会擦除当前字符串并放入一个新字符串,这会将光标移动到最后并覆盖您要对其进行的任何编辑原始字符串。您可以自行进行修改,调用colorText然后返回NO,这将进行编辑,但您仍然会遇到光标问题。

解决方法是获取光标范围,手动编辑,调用colorText,将光标放回原来的位置,然后返回NO。我知道这听起来很复杂,但代码并不太糟糕。

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    UITextPosition *beginning = textField.beginningOfDocument;
    UITextPosition *cursorLocation = [textField positionFromPosition:beginning offset:(range.location + string.length)];

    textField.text = [textField.text stringByReplacingCharactersInRange:range withString:string];

    [textField colorText]; // or however you call this on your field

    // cursorLocation will be (null) if you're inputting text at the end of the string
    // if already at the end, no need to change location as it will default to end anyway
    if(cursorLocation)
    {
        // set start/end location to same spot so that nothing is highlighted
        [textField setSelectedTextRange:[textField textRangeFromPosition:cursorLocation toPosition:cursorLocation];
    }

    return NO;
}