NSTextAttachmentCell имеет высоту в милю - PullRequest
6 голосов
/ 19 декабря 2011

Я редактирую подмножество 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, и полученная разметка была необычно грязной - в частности, я не смог найти способ красиво обернуть текст в

tags.


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

- (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;
}

1 Ответ

5 голосов
/ 04 января 2012

Попробуйте изменить метод cellFrameForTextContainer:proposedLineFragment:glyphPosition: вашего класса ячеек, чтобы он возвращал NSZeroPoint для источника кадра ячейки.

(я понятия не имею, почему это должно работать, но спрашивающий и я были живыотладка, и это на самом деле.)


Добавлено автором вопроса: Похоже, даже если возвращаемый прямоугольник описывается как "рамка", его происхождение относительнов строке, а не в верхней части документа.Таким образом, значение origin.y возвращаемого значения должно быть установлено равным нулю, если вы хотите, чтобы оно было в той же строке.

(Значение origin.x, с другой стороны, действительно относится кположение ячейки в линии, поэтому оно должно совпадать с lineFrag.origin.x, если вы не хотите изменить горизонтальное положение ячейки.)

...