2013-09-22 8 views
12

Ich versuche, Absätze von hervorgehoben in einem NSTextView anzuzeigen. Im Moment mache ich das, indem ich einen NSAttributedString mit einer Hintergrundfarbe erstelle. Hier einige vereinfachte Code:NSAttributedString Highlight/Hintergrundfarbe zeigt zwischen den Zeilen (hässlich)

NSDictionary *attributes = @{NSBackgroundColorAttributeName:NSColor.greenColor}; 
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:@"Here is a single line of text with single spacing" attributes:attributes]; 

[textView.textStorage setAttributedString:attrString]; 

Dieser Ansatz grundsätzlich funktioniert, dass es produziert markierten Text.

Single line single spaced

Leider, wenn mehrere Zeilen vorhanden sind, erstreckt sich der Höhepunkt den vertikalen Raum zwischen die Linien zusätzlich zu den Linien selbst, in Hässlichkeit zur Folge hat.

Multi line double spaced text

Kennt jemand eine Möglichkeit, diese Art zu tun, in Cocoa hervorzuheben? Das Bild unten ist im Grunde, was ich suche (ignorieren Sie die Schatten auf den weißen Kästen):

whiteout text

Ich würde bereit sein, Coretext, HTML, oder was auch immer notwendig ist, um die Dinge schöner aussehen .

+2

Haben Sie das jemals gelöst, habe ich genau das gleiche Problem – user499846

+1

Ich habe das nicht wirklich herausgefunden, aber ich habe herausgefunden, wie man die Auswahl rect um den Text mindestens zentrieren, so dass es nicht alles über oder ist unten. Es beinhaltet die Berechnung der '[paragraphStyle setLineSpacing: xx]' und '[paragraphStyle setLineHeightMultiple: xx]' so, dass sie gleich sind. Auch dies löst das eigentliche Problem nicht, macht es nur erträglicher. – stevel

Antwort

0

Try this: -

 -(IBAction)chooseOnlylines:(id)sender 
{ 

NSString *allTheText =[tv string]; 
    NSArray *lines = [allTheText componentsSeparatedByString:@"\n"]; 
    NSString *str=[[NSString alloc]init]; 
    NSMutableAttributedString *attr; 
    BOOL isNext=YES; 
    [tv setString:@""]; 
    for (str in lines) 
    { 
     attr=[[NSMutableAttributedString alloc]initWithString:str]; 
     if ([str length] > 0) 
     { 

     NSRange range=NSMakeRange(0, [str length]); 
     [attr addAttribute:NSBackgroundColorAttributeName value:[NSColor greenColor] range:range]; 
     [tv .textStorage appendAttributedString:attr]; 
      isNext=YES; 
     } 
     else 
     { 
      NSString *[email protected]"\n"; 
      NSAttributedString *attr=[[NSAttributedString alloc]initWithString:str]; 
      [tv .textStorage appendAttributedString:attr]; 
      isNext=NO; 
     } 
     if (isNext==YES) 
     { 
      NSString *[email protected]"\n"; 
      NSAttributedString *attr=[[NSAttributedString alloc]initWithString:str]; 
      [tv .textStorage appendAttributedString:attr]; 

     } 
    } 
} 
+0

Leider sind in diesem Fall die Zeilen nicht durch \ n Zeichen getrennt - dies ist ein Absatz, so dass der Text automatisch umbrochen wird. Danke für den Versuch. – stevel

+0

Ich habe den Code geändert. Bitte versuchen Sie es jetzt und es wird auch nicht die Worte wringen. –

2

Sie müssen NSLayoutManager Unterklasse und überschreiben:

- (void)fillBackgroundRectArray:(const CGRect *)rectArray 
         count:(NSUInteger)rectCount 
      forCharacterRange:(NSRange)charRange 
         color:(UIColor *)color; 

Dies ist die primitive Methode zur Hintergrundfarbe Rechtecke zeichnen.

+1

Wie Sie die oben beschriebene Methode implementieren, hängt von Ihrer Anwendung ab. Aber als zusätzlichen Kontext verwendete ich '- (void) enumerateLineFragmentsForGlyphRange: (NSRange) glyphRange usingBlock: (void (^) (CGRect rect, CGRect usedRect, NSTextContainer * textContainer, NSRange glyphRange, BOOL * stoppen)) block' um ein Array von CGRect-Strukturen zu erstellen, die die von den Zeichen-Glyphen verwendeten Grenzen beschrieben, und Schnittpunkte mit den rectArray-Inhalten erstellt haben, um die Grenzen meiner Hervorhebungen einzuschränken. – nzeltzer