【问题标题】:NSTextStorage Syntax MarkdownNSTextStorage 语法标记
【发布时间】:2016-02-20 11:12:25
【问题描述】:

我正在为 iOS/osx 编写语法降价。

它是 NSTextStorage 的子类。它在 iOS 中运行良好,但在 OSX 中(在将代码转换为 UIColor 到 NSColor 和 UIFont 到 NSFont 之后)它运行得非常好。如果我在当前行的末尾写它会很好,但是如果我将插入符号位置更改为文本中间,就在键入 1 个字母后,它会将插入符号位置更改为行尾。这只是在 OSX 中发生,因为在 IOS 中效果很好。

我知道问题出在- (void)setAttributes:(NSDictionary *)attrs range:(NSRange)range,但不知道如何解决...有什么帮助吗?

- (NSString *)string {
    return [_backingStore string];
}

- (NSDictionary *)attributesAtIndex:(NSUInteger)location effectiveRange:(NSRangePointer)range {
    return [_backingStore attributesAtIndex:location effectiveRange:range];
}

- (void)replaceCharactersInRange:(NSRange)range withString:(NSString*)str {

    [self beginEditing];
    [_backingStore replaceCharactersInRange:range withString:str];
    [self edited:NSTextStorageEditedCharacters | NSTextStorageEditedAttributes range:range changeInLength:str.length - range.length];
    [self endEditing];

}

- (void)setAttributes:(NSDictionary *)attrs range:(NSRange)range {

    [self beginEditing];
    [_backingStore setAttributes:attrs range:range];
    [self edited:NSTextStorageEditedAttributes range:range changeInLength:0];
    [self endEditing];

}

- (void)processEditing {

    [self performReplacementsForRange:[self editedRange]];
    [super processEditing];
}

- (void)performReplacementsForRange:(NSRange)changedRange {

    NSString* backingString = [_backingStore string];
    NSRange extendedRange = extendedRange = NSUnionRange(changedRange, [backingString lineRangeForRange:NSMakeRange(NSMaxRange(changedRange), 0)]);
    [self applyStylesToRange:extendedRange];
}

- (void)applyStylesToRange:(NSRange)searchRange {

    NSDictionary* attributeDictionary = self.attributeDictionary;
    NSString* backingString = [_backingStore string];
    NSDictionary* bodyAttributes  = self.bodyAttributes;
    [self setAttributes:bodyAttributes range:searchRange];
    [attributeDictionary enumerateKeysAndObjectsUsingBlock:^(NSRegularExpression* regex, NSDictionary* attributes, BOOL* stop) {
        [regex enumerateMatchesInString:backingString options:0 range:searchRange
                             usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop) {
                                 NSRange matchRange = [match rangeAtIndex:1];
                                 [self addAttributes:attributes range:matchRange];
                             }];
    }];

}

【问题讨论】:

标签: ios objective-c macos nstextstorage


【解决方案1】:

我不熟悉 NSTextStorage,但我设法通过覆盖 fixAttributesInRange: 而不是 processEditing 来解决这个问题。

代替

- (void)processEditing {

    [self performReplacementsForRange:[self editedRange]];
    [super processEditing];
}

- (void)fixAttributesInRange:(NSRange)range {
    [self performReplacementsForRange:range];
    [super fixAttributesInRange:(NSRange)range];
}

顺便说一句:applyStylesToRange 不应该嵌套在 beginEditingendEditing 之间吗?

【讨论】:

  • 嗨,嵌套在 beginEditing 和 endEditing 之间的 applyStylesToRange 没有任何不同。你是如何覆盖 fixAttributesInRange 的?你能分享你的解决方案吗?谢谢
  • beginEditing 和 endEditing 之间的更改被缓冲和一次性处理。
  • 谢谢,但它只适用于罗马字符。如果我加载了另一个像日语这样的键盘方案,它会不断替换相同的字母并且在我输入字符后不会向前移动光标......奇怪的东西......
  • 我认为在 Helvetica Neue 中看不到日文字符。在applyStylesToRange: 末尾拨打[_backingStore fixAttributesInRange:searchRange]
  • 查看"Modifying NSTextStorage causes insertion point to move to the end of the line" 和我的回答,这个快速修复不是必需的(并且可能会导致额外的麻烦,因为您的亮点现在可以免于属性修复)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-21
  • 2013-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多