NSTextAttachmentCell в милю высотой

Я редактирую подмножество HTML в NSTextView[1] и хочу имитировать тег


.

Я понял, что это можно сделать с помощью NSTextAttachment и пользовательского NSTextAttachmentCell, и у меня есть весь код, написанный для вставки вложения и ячейки. Проблема в том, что под ячейкой остается огромное количество пустого пространства.

Это пространство не является частью самой ячейки - если я закрашу всю область ячейки красным цветом, она будет точно правильного размера, но текстовое представление помещает следующую строку текста очень далеко под красным цветом. Кажется, что размер зависит от того, сколько текста находится над ячейкой; к сожалению, я работаю с длинными документами, где теги


имеют решающее значение, и это вызывает большие проблемы с приложением.

Что, черт возьми, происходит?

Денежные части моего подкласса ячеек:

- (NSRect)cellFrameForTextContainer:(NSTextContainer *)textContainer 
               proposedLineFragment:(NSRect)lineFrag glyphPosition:(NSPoint)position 
                     characterIndex:(NSUInteger)charIndex {
    lineFrag.size.width = textContainer.containerSize.width;

    lineFrag.size.height = topMargin + TsStyleBaseFontSize * 
        heightFontSizeMultiplier + bottomMargin;

    return lineFrag;
}

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView 
       characterIndex:(NSUInteger)charIndex 
        layoutManager:(NSLayoutManager *)layoutManager {
    NSRect frame = cellFrame;
    frame.size.height -= bottomMargin;

    frame.size.height -= topMargin;
    frame.origin.y += topMargin;

    frame.size.width *= widthPercentage;
    frame.origin.x += (cellFrame.size.width - frame.size.width)/2;

    [color set];
    NSRectFill(frame);
}

[1] Я попробовал WebView с установленным isEditable, и разметка, которую он произвел, была необычайно грязной - в частности, я не смог найти способ красиво обернуть текст в теги

.


В ответ на просьбу Роба Кенигера о коде, который вставляет вложение по горизонтальному правилу:

- (void)insertHorizontalRule:(id)sender {
    NSAttributedString * rule = [TsPage newHorizontalRuleAttributedStringWithStylebook:self.book.stylebook];

    NSUInteger loc = self.textView.rangeForUserTextChange.location;

    if(loc == NSNotFound) {
        NSBeep();
        return;
    }

    if(loc > 0 && [self.textView.textStorage.string characterAtIndex:loc - 1] != '\n') {
        NSMutableAttributedString * workspace = rule.mutableCopy;
        [workspace.mutableString insertString:@"\n" atIndex:0];
        rule = workspace;
    }

    if([self.textView shouldChangeTextInRange:self.textView.rangeForUserTextChange replacementString:rule.string]) {
        [self.textView.textStorage beginEditing];
        [self.textView.textStorage replaceCharactersInRange:self.textView.rangeForUserTextChange withAttributedString:rule];
        [self.textView.textStorage endEditing];
        [self.textView didChangeText];
    }

    [self.textView scrollRangeToVisible:self.textView.rangeForUserTextChange];

    [self reloadPreview:sender];
}

И метод в TsPage, который строит строку вложения:

+ (NSAttributedString *)newHorizontalRuleAttributedStringWithStylebook:(TsStylebook*)stylebook {
    TsHorizontalRuleCell * cell = [[TsHorizontalRuleCell alloc] initTextCell:@"—"];
    cell.widthPercentage = 0.33;
    cell.heightFontSizeMultiplier = 0.25;
    cell.topMargin = 12.0;
    cell.bottomMargin = 12.0;
    cell.color = [NSColor blackColor];

    NSTextAttachment * attachment = [[NSTextAttachment alloc] initWithFileWrapper:nil];
    attachment.attachmentCell = cell;
    cell.attachment = attachment;

    NSAttributedString * attachmentString = [NSAttributedString attributedStringWithAttachment:attachment];

    NSMutableAttributedString * str = [[NSMutableAttributedString alloc] initWithString:@""];
    [str appendAttributedString:attachmentString];
    [str.mutableString appendString:@"\n"];

    return str;
}
6
задан Magnus 4 January 2012 в 00:00
поделиться