2011-12-19 20 views
5

Sto modificando un sottoinsieme di HTML in un NSTextView [1] e voglio simulare un tag > ore <.NSTextAttachmentCell è alto un miglio

Ho capito che il modo per farlo è con NSTextAttachment e un NSTextAttachmentCell personalizzato, e avere il codice tutto scritto per inserire l'allegato e la cella. Il problema è che c'è un'enorme quantità di spazio vuoto sotto la cella.

Questo spazio non fa parte della cella stessa: se dipingo l'intera area della cella in rosso, è esattamente della dimensione giusta, ma la visualizzazione del testo sta mettendo la riga successiva del testo molto al di sotto del rosso. L'importo sembra dipendere da quanto il testo è sopra la cella; sfortunatamente, sto lavorando con documenti lunghi in cui i tag <ora> sono cruciali e questo causa grossi problemi con l'app.

Cosa diavolo sta succedendo?

Le parti denaro della mia sottoclasse di cellule:

- (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] Ho provato un WebView con IsEditable set e la marcatura ha prodotto era unusably sporco, in particolare, non riuscivo a trovare un modo per avvolgere correttamente il testo nei tag <p>.


Per rispondere a richiesta di Rob Keniger per il codice che inserisce l'attacco orizzontale regola:

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

E il metodo in TsPage che costruisce la stringa di attacco:

+ (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

Can voi inserisci il codice che mostra come stai inserendo l'allegato di testo nel tuo 'NSTextView'? –

+0

Rob, ho aggiunto il codice che volevi vedere. Grazie per dare un'occhiata a questo! –

risposta

5

Provare a cambiare la metodo cellFrameForTextContainer:proposedLineFragment:glyphPosition: della classe di celle per restituire NSZeroPoint per l'origine del frame della cella.

(non ho idea del perché questo dovrebbe funzionare, ma l'interrogante e sono stato live-debug di esso, e lo fa in realtà.)


Aggiunto da intervistatore: Sembra che, anche sebbene il rect che viene restituito sia descritto come un "frame", la sua origine è relativa alla linea in cui si trova, non alla cima del documento. Pertanto, il valore origin.y del valore restituito deve essere impostato su zero se lo si desidera sulla stessa riga.

(Il valore origin.x, d'altra parte, fa riferimento alla posizione della cella nella linea, e quindi dovrebbe essere la stessa di lineFrag.origin.x meno che non si desidera modificare la posizione orizzontale della cellula.)

Problemi correlati