我已经实现了两个 NSTableView 的垂直同步。不太清楚为什么你需要三个,但无论如何。请注意,这是使用 Xamarin.Mac 库的所有 c# 代码。这些是原生 Cocoa 平台的包装器。您必须自己将其转换为 obj c/swift。这应该不难。
从笔尖醒来:
table1.EnclosingScrollView.ContentView.PostsBoundsChangedNotifications = true;
NSNotificationCenter.DefaultCenter.AddObserver (NSView.BoundsChangedNotification, BoundsDidChangeNotification, table1.EnclosingScrollView.ContentView);
table2.EnclosingScrollView.ContentView.PostsBoundsChangedNotifications = true;
NSNotificationCenter.DefaultCenter.AddObserver (NSView.BoundsChangedNotification, BoundsDidChangeNotification, table2.EnclosingScrollView.ContentView);
因此,每当其中一个表滚动时,就会调用 BoundsDidChangeNotification,它负责同步 y 轴。请注意,即使由于惯性滚动或边界的编程更改(或放大/缩小或调整视图大小等)而发生滚动,这也有效。此类事件可能并不总是触发专门用于“用户滚动”的事件,因此,这是更好的方法。Bellow 是 BoundsDidChangeNotification 方法:
public void BoundsDidChangeNotification (NSNotification o)
{
if (o.Object == table1.EnclosingScrollView.ContentView) {
var bounds = new CGRect (new CGPoint (table2.EnclosingScrollView.ContentView.Bounds.Left, table1.EnclosingScrollView.ContentView.Bounds.Top), table2.EnclosingScrollView.ContentView.Bounds.Size);
if (bounds == table2.EnclosingScrollView.ContentView.Bounds)
return;
table2.ScrollPoint (bounds.Location);
} else {
var bounds = new CGRect (new CGPoint(table1.EnclosingScrollView.ContentView.Bounds.Left, table2.EnclosingScrollView.ContentView.Bounds.Top), table1.EnclosingScrollView.ContentView.Bounds.Size);
if (table1.EnclosingScrollView.ContentView.Bounds == bounds)
return;
table1.ScrollPoint (bounds.Location);
}
}
这里没有什么太花哨的......有一些边界相等检查以避免最终的无限循环(table1告诉table2同步,然后table2 tels table1等等,永远)。AFAI 记住,如果你 ScrollPoint 到当前滚动的位置,不会触发 bounds 的变化,但是由于否则会发生无限循环,我认为额外的检查是值得的——你永远不知道在未来的 os x 版本中会发生什么。