[英]Add attributes to NSMutableAttributedString character by character
這是我的情況:
我有一個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:
返回的值attribute: atIndex: effectiveRange:
始終為零,與該屬性是否實際存在無關。 有效范圍超出了我所擁有的文本范圍。
請幫幫我。
在您的strikeText:
方法中,您只檢查attributedString 的末尾。 如果你想檢查最后一個字符,你應該檢查text.length -2
,假設文本足夠長。 此外,您在方法末尾的 removeAttribute 對我來說也沒有多大意義。
關於如何重用 Delegate-Protocol 范圍的簡單方法來僅攻擊您需要的字符:
- (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;
}
可能有更多的邊緣情況,但這是一種簡單的方法,可以滿足您的需求。
你應該試試:
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/documentation/foundation/nsattributedstringkey?language=objc
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.