将 NSTableColumn 宽度设置为其最宽行的大小

Setting NSTableColumn width to exactly the size of its widest row

我想将 NSTableColumn 的宽度设置为最宽条目的确切宽度,这样文本就不会被 ... 省略掉。为此,每当插入新的文本条目时,我都会执行以下操作:

NSCell *cell = [tableView preparedCellAtColumn:0 row:idx];
NSSize size = [cell cellSize];

if(size.width > widestWidth) {
    [tableColumn setWidth:size.width];
    widestWidth = size.width;
}

不幸的是,cellSize 返回的宽度似乎有几分偏差,因为最后一个字符仍然被 ... 省略了。我可以通过向 size.width 添加大约 8 个点来轻松解决问题,但当然我想避免这种情况,因为可能有不同的字体配置,其中 8 个点是不够的,我也想要 NSTableColumn宽度 完全 适合其最宽条目的宽度。

这就是我想问的原因:如何获得行的 精确 宽度,以便我可以将其传递给 NSTableColumn::SetWidth,以便 NSTableColumn的宽度正好是最宽行的宽度?

当我 运行 使用手动引用计数并使用方法 dataCellForTableColumn: 测量 [cell cellSize].width 的旧基于单元格的演示时,我得到了第一个图像中列出的数组项的值。当我将列宽设置为 60(通过将最长字符串长度 59.33 向上舍入)时,没有问题。当我将 col 宽度设置为 59(通过向下舍入)时,我得到了 Charge... 的省略号。我无法解释为什么 'Bengals' 的单元格宽度大于 'Chargers'。 'team' 是从另一个方法 objectValueForTableColumn: 中获取的,我的方法与调用它们的顺序有关吗?第二张图片通过向上舍入最大单元格宽度显示了正确的结果。

我会尝试 post 如果我能把它转换成弧形的话。

根据以下示例,如果最大 cellSize.width 向上舍入,[cell cellSize].width 似乎可用于设置基于单元格的 table 视图的列宽.源代码可能是 Xcode 中的 运行,方法是将 'main.m' 替换为以下内容并删除预先提供的 AppDelegate。

#import <Cocoa/Cocoa.h>

 @interface AppDelegate : NSObject <NSApplicationDelegate, NSTableViewDelegate,  NSTableViewDataSource> {
  NSWindow *window;
 }
 @property(strong, nonatomic) NSArray *teams;
 - (void) createMenu;
 - (void) createWindow;
 @end
 
 @implementation AppDelegate
 
- (id)init{
 if(self = [super init])
 _teams = [NSArray arrayWithObjects:@"Ravens", @"Chiefs", @"Chargers", @"Bengals", nil];
 NSLog(@"teams = %@",_teams);
 return self;
}

- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
 NSLog(@"count = %lu", [_teams count]);
 return [_teams count];
}

- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
 NSString *team = [_teams objectAtIndex:row];
 NSLog(@"team = %@",team);
 return [_teams objectAtIndex:row];
}

- (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)col row:(NSInteger)row {
 NSTextFieldCell *cell = [col dataCell];
 [cell setBackgroundColor: [NSColor redColor]];
 [cell setDrawsBackground:YES];
 NSSize size = [cell cellSize];
 NSLog(@"cell width = %0.02f",size.width);
 return cell;
}

 - (void) createMenu {
 NSMenu *menubar = [NSMenu new];
 NSMenuItem *appMenuItem = [NSMenuItem new];
 [menubar addItem:appMenuItem];
 [NSApp setMainMenu:menubar];
 NSMenu *appMenu = [NSMenu new];
 NSMenuItem *quitMenuItem = [[NSMenuItem alloc] initWithTitle:@"Quit"
 action:@selector(terminate:) keyEquivalent:@"q"];
 [appMenu addItem:quitMenuItem];
 [appMenuItem setSubmenu:appMenu];
 }
 
 - (void) createWindow {
 #define _wndW  300
 #define _wndH  300
 window = [[NSWindow alloc] initWithContentRect: NSMakeRect( 0, 0, _wndW, _wndH )
 styleMask: NSWindowStyleMaskTitled | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskClosable backing: NSBackingStoreBuffered defer: NO];
 [window center];
 [window setTitle:@"Test window"];
 [window makeKeyAndOrderFront: nil];
 
// **** Table View with Scroll **** //
 NSScrollView * scrollView = [[NSScrollView alloc] initWithFrame:NSMakeRect( 20, _wndH - 230, _wndW - 40, 200)];
 [scrollView setBorderType:NSBezelBorder];
 [scrollView setHasVerticalScroller:YES];
 [scrollView setAutohidesScrollers:YES];
 
 NSTableView *tableView = [[NSTableView alloc] initWithFrame:NSMakeRect(0, 0, 180, 200)];
 NSTableColumn *column1 = [[NSTableColumn alloc] initWithIdentifier:@"Col1"];
 [[column1 headerCell] setStringValue:@"Teams"];
 //Change this to 59 to see ellipsis : longest [cell cellSize].width = 59.33
 [column1 setWidth: 60];
 [tableView addTableColumn:column1];
 [tableView setDelegate:self];
 [tableView setDataSource:self];
 [tableView reloadData];
 
 // **** Embed table view into scroll view, and add scroll view to window
 [scrollView setDocumentView:tableView];
 [[window contentView] addSubview:scrollView];
  
// ***** Quit btn ***** //
 NSButton *quitBtn = [[NSButton alloc]initWithFrame:NSMakeRect( _wndW - 50, 5, 40, 40 )];
 [quitBtn setBezelStyle:NSBezelStyleCircular ];
 [quitBtn setTitle: @"Q" ];
 [quitBtn setAction:@selector(terminate:)];
 [[window contentView] addSubview: quitBtn];

 }
 
 - (void) applicationWillFinishLaunching: (NSNotification *)notification {
 [self createMenu];
 [self createWindow];
 }
 
 - (void) applicationDidFinishLaunching: (NSNotification *)notification {
 }
 @end
 
 int main() {
  NSApplication *application = [NSApplication sharedApplication];
  AppDelegate *myDelegate = [[AppDelegate alloc] init];
  [application setDelegate:myDelegate];
  [application run];
  return 0;
 }