【问题标题】:Setting NSTableColumn width to exactly the size of its widest row将 NSTableColumn 宽度设置为其最宽行的大小
【发布时间】:2021-02-25 15:46:06
【问题描述】:

我想将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的宽度正好最宽的那一排?

【问题讨论】:

  • 尝试: 1. 获取输入到表格视图中的字符串。 2. 使用 NSString:sizeWithAttributes 检查边界框。 3. 如果字符串太长而无法容纳,请相应地设置列宽。
  • @apodidae:没用。 sizeWithAttributes 的结果甚至比 cellSize 返回的结果还要少。对于字符串Test item,我从cellSize 获得59 分,从sizeWithAttributes 获得55 分。
  • 有趣的是,文本将完全适合 sizeWithAttributes 计算的边界框,但不适合应该具有相同宽度的 tableView 列。
  • 我觉得更奇怪的是cellSize返回的值不够用。
  • 但是我怎样才能得到这个填充值呢?

标签: objective-c macos cocoa nstableview


【解决方案1】:

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

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

【讨论】:

  • 确实,只需在size.width 上使用ceil() 即可解决问题。非常感谢!
【解决方案2】:

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

如果我将源代码转换为 arc,我会尝试发布。

【讨论】:

    猜你喜欢
    • 2019-01-11
    • 2011-03-02
    • 1970-01-01
    • 2013-06-25
    • 2018-10-19
    • 1970-01-01
    • 2020-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多