52

いくつNSTableViewかのテキスト列があります。デフォルトではdataCell、これらの列の は Apple のNSTextFieldCellクラスのインスタンスであり、あらゆる種類の素晴らしいことを行いますが、セルの上部に揃えてテキストを描画し、テキストをセルの垂直方向の中央に配置したいと考えています。

NSTextFieldCellテキストを垂直方向に中央揃えするために使用できる内部フラグがあり、美しく機能します。ただし、これは内部フラグであるため、その使用は Apple によって認可されておらず、将来のリリースで警告なしに単に消える可能性があります。シンプルで効果的なので、現在この内部フラグを使用しています。Apple は明らかにこの機能の実装に時間を費やしてきたので、私はそれを再実装するという考えは好きではありません。

そう; 私の質問はこれです: Apple の NStextFieldCell とまったく同じように動作するものを実装する正しい方法は何ですか?

記録のために、これが私の現在の「解決策」です:

@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

次のように使用します。

[[myTableColumn dataCell] setVerticalCentering:YES];
4

7 に答える 7

37

他の回答は、複数の行では機能しませんでした。そのため、最初は文書化されていないcFlags.vCenteredプロパティを使用し続けましたが、それが原因でアプリがアプリ ストアから拒否されました。最終的に、複数行、ワード ラップ、切り捨てられた最後の行で機能する Matt Bell のソリューションの修正版を使用することになりました。

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

(このコードは ARC を想定しています。手動のメモリ管理を使用する場合は、attrString.mutableCopy の後に autorelease を追加してください)

于 2012-03-03T14:46:54.803 に答える
5

マット・ボールの方法を使用してこれを試みている人にとってdrawInteriorWithFrame:inView:は、セルを描画するように設定している場合、これはもはや背景を描画しません。これを解決するには、次の行に沿って何かを追加します

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

メソッドの先頭にdrawInteriorWithFrame:inView:

于 2010-08-02T22:19:09.010 に答える
4

参考までに、これはうまく機能しますが、セルを編集するときに中央に配置することはできませんでした...大量のテキストを含むセルがあり、このコードにより、テキストの高さが大きくなるとセルがずれることがあります次に、垂直方向に中央揃えしようとしているセルです。変更した方法は次のとおりです。

- (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;
}
于 2009-08-16T23:47:22.213 に答える
3

いいえ。正しい方法は、フィールドを別のビューに配置し、自動レイアウトまたはその親ビューのレイアウトを使用して配置することです。

于 2014-11-22T15:59:26.603 に答える
2

これはかなり古い質問ですが...

NSTableView 実装のデフォルトのスタイルは、すべて同じサイズとフォントの単一行テキスト表示を厳密に意図していると思います。

そんな時におすすめなのが、

  1. フォントを設定します。
  2. 調整しrowHeightます。

たぶん、静かに密集した列になるでしょう。そして、設定してパディングを与えますintercellSpacing

例えば、

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

ここでは、2 つのプロパティ調整で得られるものを示します。

ここに画像の説明を入力

これは複数行のテキストでは機能しませんが、複数行のサポートが必要ない場合は、垂直方向の中央揃えをすばやく行うには十分です。

于 2013-10-19T21:48:22.300 に答える
1

私は同じ問題を抱えていましたが、ここに私がした解決策があります:

1) Interface Builder で、NSTableCellView を選択します。サイズインスペクターで行の高さと同じ大きさであることを確認してください。たとえば、行の高さが 32 の場合、セルの高さを 32 にします。

2)セルが行に適切に配置されていることを確認してください(表示されていることを意味します)

3)セル内の TextField を選択し、サイズインスペクタに移動します

4)「配置」項目が表示され、「コンテナの垂直方向に中央揃え」を選択する必要があります

--> TextField はセルの中央に配置されます

于 2014-07-10T15:09:38.983 に答える