如何使用自定义NSTextStorage清除UITextView? [仅限iOS7]

时间:2014-01-13 17:41:23

标签: ios objective-c uitextview textkit nstextstorage

我目前正在尝试创建类似SMS的屏幕,用户可以在其中编写一些文本并将其发送给其他用户。一切都按预期进行,直到我尝试清除文本视图并遇到崩溃。 我一直试图找到解决这个问题的方法,但我在网上找不到足够的文档。所以在这里,希望你们其中一个人能够解决这个问题。


实施

我的UITextView是Peter Steinberger's implementation for iOS7的子类,我将它与自定义的NSTextStorage子类一起使用,如objc.io的“了解TextKit”,尤其是source code所示,以突出显示用户名消息。

在我的ViewController中,我配置了我的文本存储:

self.textStorage = [[[MyCustomTextStorage alloc] init] autorelease]; [self.textStorage addLayoutManager:self.textView.layoutManager];

然后在我的TextView的委托方法中:

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text

我将输入存储在我的自定义TextStorage中:

[self.textStorage.string stringByReplacingCharactersInRange:range withString:text];

崩溃

我可以通过self.textStorage.string检索我的文本,然后通过替换输入字符串范围内的字符来清除文本视图。这很有效,但是当我尝试再次将TextView设置为第一个响应者时,应用程序崩溃了。

Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSCFString _getBlockStart:end:contentsEnd:forRange:stopAtLineSeparators:]: Range {5, 0} out of bounds; string length 0'

提到的范围是我先前清除的字符串的范围,所以看起来我可以清除显示,但我的TextStorage / TextView保留了对第一个编辑范围/字符串的引用。


有什么可能导致这次崩溃以及如何解决它的想法? 感谢您的关注;在这一点上任何帮助表示赞赏,所以如果您有一些建议,请随时发布。 :)

3 个答案:

答案 0 :(得分:0)

它崩溃的原因是因为你使用的是一个超出textStorage字符串边界的范围。如果要清除textView,为什么不使用self.textStorage.string = @“”

答案 1 :(得分:0)

与你相同的情况。

我花了半天的时间来解决它。

  1. 您提供的示例是正确的。

  2. 您的应用不仅会在清除时崩溃,而且每次都会使用-setText:时崩溃。

  3. 他们不会崩溃,因为他们永远不会打电话给-setText: !!!

  4. 解决方案:

    将您需要的所有TextKit员工添加到您的代码中

    像这样:

    _textStorage = [[NSTextStorage alloc] init];
    _layoutManager = [[NSLayoutManager alloc] init];
    [_textStorage addLayoutManager:_layoutManager];
    _textContainer = [[NSTextContainer alloc] init];
    [_layoutManager addTextContainer:_textContainer];
    _myTextView = [[UITextView alloc] initWithFrame:frame textContainer:_textContainer];
    

    实际上,你错过了NSTextContainer,因此没有正确的容器可以输入字符串,然后应用程序崩溃了。

    也许你可以向这两个演示项目发送拉取请求,因为不要错过领导其他人。

答案 2 :(得分:0)

替换文字后,请尝试:

[self setSelectedRange:NSMakeRange(0, 0)];