2013-06-23 14 views
3

添加屬性NSMutableAttributedString字符這裏是我的情況:由字符

我曾與文本視圖沒有屬性的NSMutableAttributedString。無論何時用戶按下退格鍵,我都不希望刪除一個角色,我希望它能夠被刪除,就像生產力套件的「跟蹤更改」功能一樣。我希望用戶能夠在此之後繼續正常打字。我是這樣開始了:

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text 
{ 
if (text.length == 0 && textView.text.length == 0) return YES; 

if (text.length == 0 && !([[textView.text substringFromIndex:textView.text.length - 1] isEqualToString:@" "] || [[textView.text substringFromIndex:textView.text.length - 1] isEqualToString:@"\n"])) { 

    textView.attributedText = [self strikeText:textView.attributedText]; 

    textView.selectedRange = NSMakeRange(textView.attributedText.length - 1, 0); 

    return NO; 
} 
return YES; 
} 

- (NSAttributedString *)strikeText:(NSAttributedString *)text 
{ 
NSRange range; 
NSMutableAttributedString *returnValue = [[NSMutableAttributedString alloc] initWithAttributedString:text]; 

if (![text attribute:NSStrikethroughStyleAttributeName atIndex:text.length - 1 effectiveRange:&range]) { 
    NSLog(@"%@", NSStringFromRange(range)); 
    NSLog(@"%@", [text attribute:NSStrikethroughStyleAttributeName atIndex:text.length - 1 effectiveRange:&range]); 

    [returnValue addAttribute:NSStrikethroughStyleAttributeName value:@(NSUnderlineStyleSingle) range:NSMakeRange(text.length - 1, 1)]; 
    [returnValue addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(text.length - 1, 1)]; 
} 
else { 
    [returnValue addAttribute:NSStrikethroughStyleAttributeName value:@(NSUnderlineStyleSingle) range:NSMakeRange(range.location - 1, 1)]; 
    [returnValue addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(range.location - 1, 1)]; 
} 

[returnValue removeAttribute:NSStrikethroughStyleAttributeName range:NSMakeRange(returnValue.length, 1)]; 

return returnValue; 


} 

但是,不管我怎麼努力想,我不能換我的頭周圍的情況。此代碼不起作用,或者部分工作。 attribute: atIndex: effectiveRange:返回的值始終爲零,如果該屬性實際存在與否,則無關緊要。有效範圍超出了我所擁有的文本範圍。

請幫我看看這裏。

回答

6

在你的strikeText:方法中,你只是檢查你的Javastring的最後一個。如果你想檢查最後一個字符,你應該檢查從text.length -2,假設文本足夠長。另外你在方法結尾的removeAttribute也沒有太大意義。

你如何重複使用從委託協議的範圍內的碰撞,只有你所需要的字符,一個簡單的方法:

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text 
{ 
    // check if your replacement is going to be empty, therefor deleting 
    if ([text length] == 0) { 

     // don't strike spaces and newlines, could use NSCharacterSet here 
     NSString *textToDelete = [textView.text substringWithRange:range]; 
     if (![@[ @" ", @"\n" ] containsObject:textToDelete]) { 
      textView.attributedText = [self textByStrikingText:textView.attributedText inRange:range]; 
     } 

     textView.selectedRange = NSMakeRange(range.location, 0); 

     return NO; 
    } 

    return YES; 
} 

- (NSAttributedString *)textByStrikingText:(NSAttributedString *)text inRange:(NSRange)range 
{  
    NSMutableAttributedString *strickenText = [[NSMutableAttributedString alloc] initWithAttributedString:text]; 

    [strickenText addAttribute:NSStrikethroughStyleAttributeName value:@(NSUnderlineStyleSingle) range:range]; 
    [strickenText addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:range]; 

    return strickenText; 
} 

可能有更多的邊緣情況,但是這是一個簡單的方法是做什麼你想。

+0

不幸的是,你的代碼也有問題。我希望光標處於被擊穿的文本的末尾。如果在某些文本被觸發後輸入其他內容,新插入的文本也會被觸發。 – duci9y

+0

我用屬性atIndex:effectiveRange在第一部分中解釋了您的問題的原因。給出的代碼不應該是完整的解決方案,而是您繼續的方向。 – Karl

5

你應該嘗試:

NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:@"Hello. That is a test"]; 
[str addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:22] range:NSMakeRange(2,1)]; 
[str addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(8,2)]; 
[str addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:NSMakeRange(18,2)]; 

和屬性描述如下: https://developer.apple.com/reference/foundation/nsattributedstring/1652619-character_attributes?language=objc