簡體   English   中英

同步多個UITableView實例的滾動位置

[英]Syncing the scroll position of multiple UITableView instances

我有一個項目,我需要在iPad上的同一視圖中顯示多個UITableView實例。 它們也恰好是旋轉的,但我相當肯定這是無關緊要的。 用戶應該不知道視圖由多個表視圖組成。 因此,我想這樣做,當我滾動一個tableview時,其他人同時滾動它。

因為UITableViewUIScrollView的子類,所以我想我可以處理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;

老問題,但這是一個更簡單的方法。

  1. 將自己標記為UITableViewDelegate:

     class MultiTableViewController: UIViewController, UITableViewDelegate { ... } 
  2. 將自己設置為表視圖的委托:

     override func viewDidLoad() { super.viewDidLoad() leftTableView.delegate = self rightTableView.delegate = self } 

    (您也可以在界面構建器中執行此步驟)。

  3. 實現此方法:

     func scrollViewDidScroll(scrollView: UIScrollView) { leftTableView.contentOffset = scrollView.contentOffset rightTableView.contentOffset = scrollView.contentOffset } 

完成。

表視圖具有滾動視圖,UITableViewDelegate協議包含所有UIScrollViewDelegate方法,因此您可以使用它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM