滚动 NSTableView 使一行居中

N F*_*N F 5 cocoa objective-c

我想以编程方式滚动 NSTableView 以便特定行居中。滚动 NSTableView 以便特定行可见很简单:

[theTableView scrollRowToVisible:pos];
Run Code Online (Sandbox Code Playgroud)

但是,通常有问题的行位于可见区域的底部,而我希望它大致位于中心。

另一种愚蠢的方法是在我想要可见的行之外滚动几行,例如:

    // pos = index of desired row
    // numRows = number of rows in the table
    NSRect visibleRect = [resultsTableView visibleRect];
    NSRange visibleRange = [resultsTableView rowsInRect:visibleRect];
    NSUInteger offset = visibleRange.length/2;
    NSUInteger i;
    if (pos + offset >= numRows)
        i = numRows - 1;
    else if (pos < visibleRange.length)
        i = pos;
    else
        i = pos + offset;
    [resultsTableView scrollRowToVisible:i];
Run Code Online (Sandbox Code Playgroud)

如果所有行的高度完全相同,这将起作用,但我对制作具有不同高度的行感兴趣。

有没有更好的,也许更直接的方法来做到这一点?例如,我注意到 NSTableView 被包裹在一个 NSScrollView 中......(该表是使用 Interface Builder 制作的。)

谢谢!

Ant*_*rio 5

这对我的 NSTableView 子类有用

func scrollRowToVisible(row: Int, animated: Bool) {

    if animated {
        guard let clipView = superview as? NSClipView,
              let scrollView = clipView.superview as? NSScrollView else {

                assertionFailure("Unexpected NSTableView view hiearchy")
                return
        }

        let rowRect = rect(ofRow: row)
        var scrollOrigin = rowRect.origin

        let tableHalfHeight = clipView.frame.height * 0.5
        let rowRectHalfHeight = rowRect.height * 0.5

        scrollOrigin.y = (scrollOrigin.y - tableHalfHeight) + rowRectHalfHeight

        if scrollView.responds(to: #selector(NSScrollView.flashScrollers)) {
            scrollView.flashScrollers()
        }

        clipView.animator().setBoundsOrigin(scrollOrigin)

    } else {

        scrollRowToVisible(row)
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以打电话:

self.tableView.scrollRowToVisible(self.tableView.selectedRow, animated:true)
Run Code Online (Sandbox Code Playgroud)

选择行后


Ver*_*ous 1

我会看一下NSView-scrollPoint:方法-scrollRectToVisible:。尝试做类似的事情:

if (tableView.mainScrollView) {
    CGFloat yLocation = row.frame.origin.y + tableView.mainScrollView.contentView.frame.size.height / 2;
    if (yLocation > tableView.frame.size.height) yLocation = tableView.frame.size.height;
    NSPoint rowPoint = NSMakePoint(0, row.frame.origin.y + );
    [tableView scrollPoint:rowPoint];
}
Run Code Online (Sandbox Code Playgroud)

我不确定这是否有效,因为我无法测试它,请告诉我。