基本上,我有一个带有1列的NSTableView,我在每行插入长字符串。但是,并非所有的字符串都很长,所以我希望每行的高度根据字符串的长度而有所不同。
我已经发现我需要询问它的宽度是多少,然后询问字符串如果柱子宽那么会占用多少行,然后决定NSCell的“高”程度。但是我到底该怎么做呢?我从下面得到了柱宽:
[[[tableView tableColumns] objectAtIndex:0] width];
但我无法弄清楚如何询问NSString将占用多少空间。或者,也许,我应该采取更好的方式来做这件事?
感谢您提前提供任何帮助。
答案 0 :(得分:10)
创建NSTextFieldCell实例并匹配其字体/大小/等。到列的数据单元格。询问-cellSizeForBounds:
,传递一个具有较大高度(FLT_MAX?)的列所需宽度的矩形。结果应该是可以使用其高度的NSSize。
如果您有多个多行文本列会变得更加棘手,因为您需要考虑该行中的所有单元格,将最大值作为行高。如果你期望平均有很多行,你可能想要缓存这项工作,根据需要更新它,然后在调用行高度委托方法时简单地引用它。
答案 1 :(得分:8)
按照上述答案编码...
NSString *string = [[_tableViewDataSourceArray objectAtIndex:rowIndex]
valueForKey:@"StringToDisplay"];
NSTableColumn *tableColoumn = [aTableView
tableColumnWithIdentifier:@"TableColumnIdentifier"];
if (tableColoumn)
{
NSCell *dataCell = [tableColoumn dataCell];
[dataCell setWraps:YES];
[dataCell setStringValue:string];
NSRect myRect = NSMakeRect(0, 0, [tableColoumn width], CGFLOAT_MAX);
heightOfRow = [dataCell cellSizeForBounds:myRect].height;
}
答案 2 :(得分:3)
这是Robert D'Almeida's answer的一个小改进(我最初将其作为编辑提交,但它被拒绝了,因为“帖子的原始含义或意图将丢失”)。我添加了方法签名并进行了一些其他小改动。
- (CGFloat)tableView:(NSTableView *)aTableView heightOfRow:(NSInteger)row {
CGFloat heightOfRow = 100; // or some other default value
// get the content for this table cell from the model
NSString *string = [[_tableViewDataSourceArray objectAtIndex:rowIndex]
valueForKey:@"StringToDisplay"];
NSTableColumn *tableColumn = [aTableView
tableColumnWithIdentifier:@"TableColumnIdentifier"];
if (tableColumn) {
NSCell *dataCell = [tableColumn dataCell];
[dataCell setWraps:YES];
[dataCell setStringValue:string];
// See how tall it naturally would want to be if given a restricted
// width, but unbound height
NSRect myRect = NSMakeRect(0, 0, [tableColumn width], CGFLOAT_MAX);
heightOfRow = [dataCell cellSizeForBounds:myRect].height;
}
return heightOfRow;
}
答案 3 :(得分:2)
我喜欢Robert D'Almeida's answer,但它使用的是-[tableColumn dataCell]
,Apple的博士说#34}仅适用于基于细胞的表格视图"。
我的尝试如下。
在Interface Builder中(在Xcode中:我目前使用5.1.1),设置NSTableView。
这是一个与该设置一起使用的NSTableViewDelegate方法。这导致每个表行的高度被设置为使得"包裹列" (包含NSTextField)显示其文本而不截断。
- (CGFloat)tableView:(NSTableView *)aTableView heightOfRow:(NSInteger)aRow {
NSTableColumn *tableColumn = [aTableView tableColumnWithIdentifier:@"WrapColumnIdentifier"];
// obtain the view that would be used at this position in the table
// (ie at this column and row: I'm using this odd form of language so as
// to avoid the word "cell" and potential confusion with NSCell),
// populated with data from the model
NSView* view = [self tableView:aTableView viewForTableColumn:tableColumn row:aRow];
NSAssert([view isKindOfClass:[NSTableCellView class]], @"Expected view used in table to be NSTableCellView");
NSTableCellView* tableCellView = (NSTableCellView*)view;
// get the NSCell used by the NSTextField at this position in the table
NSCell* cell = [[tableCellView textField] cell];
// See how tall it naturally would want to be if given a restricted width,
// but unbound height
NSRect unboundHeightColumnRect = NSMakeRect(0, 0, [tableColumn width], CGFLOAT_MAX);
CGFloat cellTextHeight = [cell cellSizeForBounds:unboundHeightColumnRect].height;
// Apple's docs say this method must return a value greater than 0.
// cellTextHeight might be 0 (eg if the model returns no data at this
// position in the table). Use the row height set for the table in IB
// as the minimum.
return MAX(cellTextHeight, [tableView rowHeight]);
}
答案 4 :(得分:2)
这是另一个解决方案,在我的案例中效果很好:
<强>目标-C:强>
- (double)tableView:(NSTableView *)tableView heightOfRow:(long)row
{
if (tableView == self.tableViewTodo)
{
CKRecord *record = [self.arrayTodoItemsFiltered objectAtIndex:row];
NSString *text = record[@"title"];
double someWidth = self.tableViewTodo.frame.size.width;
NSFont *font = [NSFont fontWithName:@"Palatino-Roman" size:13.0];
NSDictionary *attrsDictionary =
[NSDictionary dictionaryWithObject:font
forKey:NSFontAttributeName];
NSAttributedString *attrString =
[[NSAttributedString alloc] initWithString:text
attributes:attrsDictionary];
NSRect frame = NSMakeRect(0, 0, someWidth, MAXFLOAT);
NSTextView *tv = [[NSTextView alloc] initWithFrame:frame];
[[tv textStorage] setAttributedString:attrString];
[tv setHorizontallyResizable:NO];
[tv sizeToFit];
double height = tv.frame.size.height + 20;
return height;
}
else
{
return 18;
}
}
<强>夫特:强>
func tableView(tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
if let log:Log = logsArrayController.arrangedObjects.objectAtIndex(row) as? Log {
if let string: String = log.message! {
let someWidth: CGFloat = tableView.frame.size.width
let stringAttributes = [NSFontAttributeName: NSFont.systemFontOfSize(12)] //change to font/size u are using
let attrString: NSAttributedString = NSAttributedString(string: string, attributes: stringAttributes)
let frame: NSRect = NSMakeRect(0, 0, someWidth, CGFloat.max)
let tv: NSTextView = NSTextView(frame: frame)
tv.textStorage?.setAttributedString(attrString)
tv.horizontallyResizable = false
tv.sizeToFit()
let height: CGFloat = tv.frame.size.height + 20 // + other objects...
return height
}
}
return 100 //Fail
}