为什么我的格式化文本的范围在iOS 7中移位?

时间:2013-10-31 17:10:03

标签: ios uitextview nsattributedstring

我的应用程序包含一个文本格式设置工具,提供粗体,斜体和颜色等按钮,并通过生成NSAttributedString并将其设置为UITextView的attributedText属性来显示格式化文本。在用户选择文本并点击按钮后,我获取UITextView的selectedRange属性,然后获取UITextView的当前attributesText属性,根据所选范围向文本添加另一个属性,然后将其分配回attributionText属性再次使用UITextView。

从iOS 7开始,我的文本格式开始显示在文本中的错误位置,通常会向前移动几个字符。经过一些测试后,我注意到这只发生在一个空行之后(例如,一段文本后面有两个换行符),并且格式化为每个空行前一个字符偏移。

经过更多测试后,我发现当我第一次设置attributedText属性时,任何两个换行符的序列都会更改为换行符,然后是“行分隔符”字符(Unicode 8232),然后是第二个换行符。新的字符肯定是由attributionText赋值添加的,正如我可以看到在该操作之前和之后立即输出每个字符的整数值。但是,UITextView的selectedRange属性会忽略行分隔符,因此它返回的任何范围现在都不正确。

我已经找到了一种解决方法,我稍后会将其作为答案添加。我主要发布这个以防万一其他人遇到问题。另外,我已经向Apple报告了这个错误15349335。

1 个答案:

答案 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,具体取决于我想要调整的方式。这已经为我工作了几个星期了,但是如果有人有替代解决方案,我很想看到它。