我的应用程序包含一个文本格式设置工具,提供粗体,斜体和颜色等按钮,并通过生成NSAttributedString并将其设置为UITextView的attributedText属性来显示格式化文本。在用户选择文本并点击按钮后,我获取UITextView的selectedRange属性,然后获取UITextView的当前attributesText属性,根据所选范围向文本添加另一个属性,然后将其分配回attributionText属性再次使用UITextView。
从iOS 7开始,我的文本格式开始显示在文本中的错误位置,通常会向前移动几个字符。经过一些测试后,我注意到这只发生在一个空行之后(例如,一段文本后面有两个换行符),并且格式化为每个空行前一个字符偏移。
经过更多测试后,我发现当我第一次设置attributedText属性时,任何两个换行符的序列都会更改为换行符,然后是“行分隔符”字符(Unicode 8232),然后是第二个换行符。新的字符肯定是由attributionText赋值添加的,正如我可以看到在该操作之前和之后立即输出每个字符的整数值。但是,UITextView的selectedRange属性会忽略行分隔符,因此它返回的任何范围现在都不正确。
我已经找到了一种解决方法,我稍后会将其作为答案添加。我主要发布这个以防万一其他人遇到问题。另外,我已经向Apple报告了这个错误15349335。
答案 0 :(得分:0)
我编写了这个方法来调整selectedRange属性返回的范围,以便考虑这些额外的行分隔符:
- (NSRange)adjustRangeForEmptyLines:(NSRange)range inText:(NSAttributedString *)text byChars:(int)chars {
int emptyLinesBeforeRange = 0;
int emptyLinesWithinRange = 0;
for (int i=0; i<(range.location + range.length); i++) {
int thisCharacter = [text.string characterAtIndex:i];
//NSLog(@"thisCharacter: %i", thisCharacter);
if (thisCharacter == 8232) {
if (i < range.location) {
emptyLinesBeforeRange++;
} else {
emptyLinesWithinRange++;
}
}
}
//NSLog(@"found %i + %i empty lines", emptyLinesBeforeRange, emptyLinesWithinRange);
range.location += (emptyLinesBeforeRange * chars);
range.length += (emptyLinesWithinRange * chars);
return range;
}
我可以将byChars参数设置为1或-1,具体取决于我想要调整的方式。这已经为我工作了几个星期了,但是如果有人有替代解决方案,我很想看到它。