5

特定の行が中央に配置されるように、プログラムでNSTableViewをスクロールしたいと思います。NSTableViewをスクロールして、特定の行が表示されるようにするのは簡単です。

[theTableView scrollRowToVisible:pos];

ただし、通常、問題の行は表示領域の下部にありますが、私はそれをほぼ中央に配置したいと思います。

もう1つの愚かなアプローチは、表示したい行を超えて数行スクロールすることです。たとえば、次のようになります。

    // 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];

これは、すべての行がまったく同じ高さの場合に機能しますが、異なる高さの行を作成することに興味があります。

これを行うためのより良い、おそらくより直接的な方法はありますか?たとえば、NSTableViewがNSScrollViewにラップされていることに気づきました...(テーブルはInterface Builderを使用して作成されました)。

ありがとう!

4

5 に答える 5

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)
    }
}

次に、次のように呼び出すことができます。

self.tableView.scrollRowToVisible(self.tableView.selectedRow, animated:true)

行を選択した後

于 2016-06-05T05:31:27.613 に答える
3

Swift 4 で解決策を探しているときに、この質問に出くわしました (私が移植した回答に対して @AntoniodePerio に感謝します)。

extension NSTableView {
    func centreRow(row: Int, animated: Bool) {
        self.selectRowIndexes(IndexSet.init(integer: row), byExtendingSelection: false)
        let rowRect = self.frameOfCell(atColumn: 0, row: row)
        if let scrollView = self.enclosingScrollView {
            let centredPoint = NSMakePoint(0.0, rowRect.origin.y + (rowRect.size.height / 2) - ((scrollView.frame.size.height) / 2))
            if animated {
                scrollView.contentView.animator().setBoundsOrigin(centredPoint)
            } else {
                self.scroll(centredPoint)
            }
        }
    }
}

次のように呼び出します。

@IBOutlet weak var myTable: NSTableView! myTable.centreRow(row: 10, animated: true)

于 2018-03-09T11:14:10.557 に答える
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];
}

これが機能するかどうかはわかりません。テストできないため、お知らせください。

于 2012-08-02T02:09:12.953 に答える
0

これは私にとってはうまくいきます.. https://stackoverflow.com/a/8480325/804616
しかし、ビューがすでに表示されているかどうかに基づいて、コードを条件付きで呼び出すことができます。

于 2012-08-23T19:36:50.610 に答える