NSA*_*ict 17 macos cocoa objective-c nstableview autolayout
我之前曾问过这个问题,但我对解决方案不太满意.
我想NSTableView在一个NSPopover或一个中显示一个NSWindow.
现在,窗口的大小应该根据表格视图进行调整.
就像Xcode一样:
 

使用自动布局时,这非常简单,您可以将内部视图固定到超级视图.
我的问题是,我无法弄清楚表格视图的最佳高度.以下代码枚举所有可用行,但它不返回正确的值,因为表视图具有其他元素,如分隔符和表头.
- (CGFloat)heightOfAllRows:(NSTableView *)tableView {
    CGFloat __block height;
    [tableView enumerateAvailableRowViewsUsingBlock:^(NSTableRowView *rowView, NSInteger row) {
        // tried it with this one
        height += rowView.frame.size.height;
        // and this one
        // height += [self tableView:nil heightOfRow:row];
    }];
    return height;
}
我怎样才能解决这个问题?如何正确计算表格视图所需的高度.
我应该在哪里运行此代码?
我不想在控制器中实现它,因为它肯定是表视图应该自己处理的东西.
我甚至没有找到任何有用的委托方法.
所以我认为最好是你可以继承NSTableView.
那么我的问题2,在哪里实现它?
绝对值得赏心悦目
此答案适用于Swift 4,针对macOS 10.10及更高版本:
1.回答
您可以使用表格视图fittingSize来计算弹出窗口的大小。
tableView.needsLayout = true
tableView.layoutSubtreeIfNeeded()
let height = tableView.fittingSize.height
2.回答
我了解您希望将代码移出视图控制器的愿望,但是由于表视图本身不了解项目数量(仅通过委派)或模型更改,因此我将其放在视图控制器中。从macOS 10.10开始,您可以preferredContentSize在NSViewController内部弹出窗口中使用它来设置大小。
func updatePreferredContentSize() {
    tableView.needsLayout = true
    tableView.layoutSubtreeIfNeeded()
    let height = tableView.fittingSize.height
    let width: CGFloat = 320
    preferredContentSize = CGSize(width: width, height: height)
}
在我的示例中,我使用的是固定宽度,但是您也可以使用计算出的宽度(尚未测试过)。
每当数据源更改和/或要显示弹出窗口时,您都希望调用update方法。
希望这能解决您的问题!
您可以查询最后一行的框架以获取表视图的高度:
- (CGFloat)heightOfTableView:(NSTableView *)tableView
{
    NSInteger rows = [self numberOfRowsInTableView:tableView];
    if ( rows == 0 ) {
        return 0;
    } else {
        return NSMaxY( [tableView rectOfRow:rows - 1] );
    }
}
这假设一个没有边框的封闭滚动视图!
您可以查询tableView.enclosingScrollView.borderType以检查滚动视图是否有边界.如果是,则需要将边框宽度添加到结果中(两次;底部和顶部).不幸的是,我不知道如何获得边框宽度.
查询的优点rectOfRow:是它在与a相同的runloop迭代中工作[tableView reloadData];.根据我的经验,当您reloadData第一次执行时,查询表视图的框架不能可靠地工作(您将获得之前的高度).
Xcode 中的 Interface Builder 会自动将 NSTableView 放入 NSScrollView 中。NSScrollView 是标题实际所在的位置。创建一个 NSScrollView 作为窗口中的基础视图,并向其中添加 NSTableView:
NSScrollView * scrollView = [[NSScrollView alloc]init];
[scrollView setHasVerticalScroller:YES];
[scrollView setHasHorizontalScroller:YES];
[scrollView setAutohidesScrollers:YES];
[scrollView setBorderType:NSBezelBorder];
[scrollView setTranslatesAutoresizingMaskIntoConstraints:NO];
NSTableView * table = [[NSTableView alloc] init];
[table setDataSource:self];
[table setColumnAutoresizingStyle:NSTableViewUniformColumnAutoresizingStyle];
[scrollView setDocumentView:table];
//SetWindow's main view to scrollView
现在你可以询问scrollView的contentView来找到NSScrollView的大小
NSRect rectOfFullTable = [[scrollView contentView] documentRect];
因为 NSTableView 位于 NSScrollView 内部,所以 NSTableView 将有一个 headerView,您可以使用它来查找标题的大小。
您可以子类化 NSScrollView 以在表大小更改(标题+行)时通过覆盖reflectScrolledClipView:方法来更新其超级视图
| 归档时间: | 
 | 
| 查看次数: | 8514 次 | 
| 最近记录: |