[英]Syncing the scroll position of multiple UITableView instances
我有一個項目,我需要在iPad上的同一視圖中顯示多個UITableView
實例。 它們也恰好是旋轉的,但我相當肯定這是無關緊要的。 用戶應該不知道視圖由多個表視圖組成。 因此,我想這樣做,當我滾動一個tableview時,其他人同時滾動它。
因為UITableView
是UIScrollView
的子類,所以我想我可以處理UIScrollViewDelegate
方法並將它們傳遞給所有的tableview。 不幸的是,雖然我可以捕獲一些事件,但是方法調用粒度不夠好,而且我在將這些消息傳遞給其他tableviews時遇到了麻煩。 我能得到的最接近的是實現-scrollViewDidScroll:
然后在每個tableview上調用-scrollViewDidScroll:
-setContentOffset:animated
。 如果我嘗試為所有可能的情況發送此消息,我最終會鎖定,因為-scrollViewDidScroll
正在調用我的-scrollViewDidScroll
-setContentOffset:animated
調用,所以我最終凍結了。 無論如何,如果我通過僅使用此方法檢測一個tableview上的滾動然后將其傳遞到其他tableviews來消除鎖定,我發現雖然其他tableviews最終滾動到同一位置,但它們落后於第二個或二。
如何在不UITableView
情況下實現此行為?
您可以通過直接觀察contentOffset
來解決回調粒度問題。 在viewDidLoad
,在需要同步的每個表視圖上設置KVO:
for(UITableView *view in self.tableViewCollection)
{
[view addObserver:self
forKeyPath:@"contentOffset"
options:NSKeyValueObservingOptionNew
context:NULL];
}
然后,當您觀察到更改時,暫時取消觀察,更新其他表視圖的偏移,然后重新開啟觀察。
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
static BOOL isObservingContentOffsetChange = NO;
if([object isKindOfClass:[UITableView class]]
&& [keyPath isEqualToString:@"contentOffset"])
{
if(isObservingContentOffsetChange) return;
isObservingContentOffsetChange = YES;
for(UITableView *view in self.tableViewCollection)
{
if(view != object)
{
CGPoint offset =
[[change valueForKey:NSKeyValueChangeNewKey] CGPointValue];
view.contentOffset = offset;
}
}
isObservingContentOffsetChange = NO;
return;
}
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
}
這可能會變得更漂亮,但它可以解決這個問題。
直接使用contentOffset
屬性而不是setContentOffset:animated
來避免延遲。 在您的示例中,將第73行和第74行更改為
self.tableViewMiddle.contentOffset = scrollView.contentOffset;
self.tableViewBottom.contentOffset = scrollView.contentOffset;
老問題,但這是一個更簡單的方法。
將自己標記為UITableViewDelegate:
class MultiTableViewController: UIViewController, UITableViewDelegate { ... }
將自己設置為表視圖的委托:
override func viewDidLoad() { super.viewDidLoad() leftTableView.delegate = self rightTableView.delegate = self }
(您也可以在界面構建器中執行此步驟)。
實現此方法:
func scrollViewDidScroll(scrollView: UIScrollView) { leftTableView.contentOffset = scrollView.contentOffset rightTableView.contentOffset = scrollView.contentOffset }
完成。
表視圖具有滾動視圖,UITableViewDelegate協議包含所有UIScrollViewDelegate方法,因此您可以使用它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.