2011-12-19 15 views
5

Edytuję podzestaw HTML w NSTextView [1] i chcę symulować tag <hr>.NSTextAttachmentCell jest wysoki na milę

Zorientowałem się, że sposobem na to jest NSTextAttachment i niestandardowy NSTextAttachmentCell, i napisać kod, aby wstawić załącznik i komórkę. Problem polega na tym, że pod komórką jest ogromna ilość pustej przestrzeni.

To spacja nie jest częścią samej komórki - jeśli pomaluję cały obszar komórki na czerwono, jest to dokładnie odpowiedni rozmiar, ale widok tekstowy powoduje umieszczenie następnej linii tekstu znacznie poniżej czerwonego. Wydaje się, że ilość zależy od ilości tekstu w komórce; niestety pracuję z długimi dokumentami, w których znaczniki są ważne, co powoduje poważne problemy z aplikacją.

Co do cholery się dzieje?

Części pieniądze mojego podklasy komórek:

- (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] próbowałem WebView z zestawem isEditable i znaczników produkowane było unusably dirty-w szczególności, nie mogłem znaleźć sposób na wygodne otwieranie tekstu w tagach <p>.


Aby odpowiedzieć na żądania Rob Keniger za kod, który wstawia poziomą przywiązanie zasada:

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

a sposób w TsPage że konstruuje ciąg Załącznik:

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

Czy ty opublikuj kod pokazujący w jaki sposób wstawiasz załącznik tekstowy do 'NSTextView'? –

+0

Rob, dodałem kod, który chciałeś zobaczyć. Dziękuję za obejrzenie tego! –

Odpowiedz

5

Spróbuj zmienić metoda klasy cellFrameForTextContainer:proposedLineFragment:glyphPosition: klasy komórkowej do zwracania NSZeroPoint dla początku ramki komórki.

(nie mam pojęcia, dlaczego to powinno działać, ale pytającego i ja live-debugowanie to, i to rzeczywiście działa.)


Dodane przez pytającego: Wygląda na to, nawet choć zwracany prostokąt jest opisany jako "ramka", jego pochodzenie jest zależne od linii, w której się znajduje, a nie od górnej krawędzi dokumentu. Dlatego wartość zwracanej wartości origin.y powinna być ustawiona na zero, jeśli chcesz ją ustawić w tym samym wierszu.

(Wartość origin.x, z drugiej strony, robi odnoszą się do położenia komórki w wierszu, więc powinien być taki sam jak lineFrag.origin.x chyba że chcesz zmienić komórki poziome położenie.)