Frage

Ich habe eine NSTableView mit mehreren Textspalten. Standardmäßig ist die dataCell für diese Spalten eine Instanz NSTextFieldCell Klasse von Apple, die alle Arten von wunderbaren Dingen tun, aber es zieht Text mit dem oberen Ende der Zelle ausgerichtet ist, und ich mag der Text vertikal in der Zelle zentriert werden.

Es gibt eine interne Flagge in NSTextFieldCell, die vertikal den Text zentrieren verwendet werden kann, und es funktioniert wunderbar. Da es jedoch ein internes Flag ist, ist seine Verwendung nicht von Apple genehmigt und es könnte einfach ohne Vorwarnung in einer zukünftigen Version verschwinden. Ich bin derzeit dieses interne Flag, weil es einfach und effektiv ist. Apple hat offensichtlich einige Zeit die Umsetzung der Funktion verbracht, so Ich mag nicht die Idee der Neuimplementierung es.

So; meine Frage ist: Was ist der richtige Weg ist, etwas zu implementieren, die genau wie Apples NStextFieldCell verhält, sondern zieht vertikal zentriert Text anstelle von oben ausgerichtet

Für das Protokoll, hier ist meine aktuelle "Lösung":

@interface NSTextFieldCell (MyCategories)
- (void)setVerticalCentering:(BOOL)centerVertical;
@end

@implementation NSTextFieldCell (MyCategories)
- (void)setVerticalCentering:(BOOL)centerVertical
{
    @try { _cFlags.vCentered = centerVertical ? 1 : 0; }
    @catch(...) { NSLog(@"*** unable to set vertical centering"); }
}
@end

wie folgt verwendet:

[[myTableColumn dataCell] setVerticalCentering:YES];
War es hilfreich?

Lösung

Die anderen Antworten nicht für mehrere Linien arbeiten. Daher setzte ich zunächst die undokumentierte cFlags.vCentered Eigenschaft verwenden, aber das verursachte mein App aus dem App Store abgelehnt. Ich landete Lösung mit einer modifizierten Version von Matt Bell, die für mehrere Zeilen, Zeilenumbruch funktioniert, und eine verkürzte letzte Zeile:

-(void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
    NSAttributedString *attrString = self.attributedStringValue;

    /* if your values can be attributed strings, make them white when selected */
    if (self.isHighlighted && self.backgroundStyle==NSBackgroundStyleDark) {
        NSMutableAttributedString *whiteString = attrString.mutableCopy;
        [whiteString addAttribute: NSForegroundColorAttributeName
                            value: [NSColor whiteColor]
                            range: NSMakeRange(0, whiteString.length) ];
        attrString = whiteString;
    }

    [attrString drawWithRect: [self titleRectForBounds:cellFrame] 
                     options: NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin];
}

- (NSRect)titleRectForBounds:(NSRect)theRect {
    /* get the standard text content rectangle */
    NSRect titleFrame = [super titleRectForBounds:theRect];

    /* find out how big the rendered text will be */
    NSAttributedString *attrString = self.attributedStringValue;
    NSRect textRect = [attrString boundingRectWithSize: titleFrame.size
                                               options: NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin ];

    /* If the height of the rendered text is less then the available height,
     * we modify the titleRect to center the text vertically */
    if (textRect.size.height < titleFrame.size.height) {
        titleFrame.origin.y = theRect.origin.y + (theRect.size.height - textRect.size.height) / 2.0;
        titleFrame.size.height = textRect.size.height;
    }
    return titleFrame;
}

(Dieser Code setzt voraus, ARC, ein Autofreigabe nach attrString.mutableCopy hinzufügen, wenn Sie manuelle Speicherverwaltung verwenden)

Andere Tipps

Übergeordnete NSCell des -titleRectForBounds: sollte es tun - das ist die Methode, die für die Zelle zu sagen, wo der Text ziehen:

- (NSRect)titleRectForBounds:(NSRect)theRect {
    NSRect titleFrame = [super titleRectForBounds:theRect];
    NSSize titleSize = [[self attributedStringValue] size];
    titleFrame.origin.y = theRect.origin.y + (theRect.size.height - titleSize.height) / 2.0;
    return titleFrame;
}

- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
    NSRect titleRect = [self titleRectForBounds:cellFrame];
    [[self attributedStringValue] drawInRect:titleRect];
}

Zu Ihrer Information, das funktioniert gut, obwohl ich es nicht geschafft haben, um es zentriert zu bleiben zu erhalten, wenn Sie die Zelle bearbeiten ... ich manchmal Zellen mit großen Mengen von Text haben und dieser Code kann dazu führen, sie, wenn der Text falsch ausgerichtet werden Höhe größer ist dann die Zelle vertikal zentriert es in es versucht, hier meine modifizierte Methode:.

- (NSRect)titleRectForBounds:(NSRect)theRect 
 {
    NSRect titleFrame = [super titleRectForBounds:theRect];
    NSSize titleSize = [[self attributedStringValue] size];
     // test to see if the text height is bigger then the cell, if it is,
     // don't try to center it or it will be pushed up out of the cell!
     if ( titleSize.height < theRect.size.height ) {
         titleFrame.origin.y = theRect.origin.y + (theRect.size.height - titleSize.height) / 2.0;
     }
    return titleFrame;
}

Für jedermann versucht, diese Matt Ball drawInteriorWithFrame:inView: Methode verwendet, wird dies nicht mehr zieht einen Hintergrund, wenn Sie Ihre Zelle gesetzt haben zu zeichnen. Um dies zu lösen etwas entlang der Linien von hinzufügen

[[NSColor lightGrayColor] set];
NSRectFill(cellFrame);

zu Beginn Ihrer drawInteriorWithFrame:inView: Methode.

Das ist zwar ziemlich alte Frage ...

Ich glaube, Standardstil von NSTableView Implementierung einzeilige Textanzeige streng für alle gleiche Größe und Schriftart bestimmt ist.

In diesem Fall empfehle ich,

  1. Stellen Sie Schriftart.
  2. Stellen Sie rowHeight.

Vielleicht werden Sie ruhig dichte Reihen erhalten. Und dann geben sie Polsterung durch intercellSpacing Einstellung.

Beispiel:

    core_table_view.rowHeight               =   [NSFont systemFontSizeForControlSize:(NSSmallControlSize)] + 4;
    core_table_view.intercellSpacing        =   CGSizeMake(10, 80);

Hier ist, was Sie mit zwei Eigenschaftseinstellung erhalten werden.

eingeben Bild Beschreibung hier

Dies funktioniert nicht für mehrzeiligen Text, aber sehr gut genug für eine schnelle vertikale Mittel wenn Sie mehrzeilige Unterstützung nicht brauchen.

Ich hatte das gleiche Problem und hier ist die Lösung, die ich habe:

1) In Interface Builder, wählen Sie Ihren NSTableCellView. Stellen Sie sicher, dass es so groß wie die Zeilenhöhe in der Größe Inspector. wenn Ihre Zeilenhöhe 32 ist zum Beispiel, stellen Sie Ihr Handy Höhe 32

2) Stellen Sie sicher, dass Ihre Zelle gut in der Reihe platziert wird (ich meine sichtbar)

3) Wählen Sie Ihre TextField- in Ihrem Handy und gehen Sie zu Ihrer Größe Inspektor

4) Sie sollten "Anordnen" Artikel sehen und wählen Sie "Vertikal zentriert in Containern"

-> Die TextField- wird sich zentriert in der Zelle

Nein. Der richtige Weg ist es, das Feld in einer anderen Ansicht zu setzen und Auto-Layout verwenden oder dieses Layout der übergeordneten Ansicht zu positionieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top