我有一个项目,我需要在 iPad 的同一 View 中显示多个 UITableView
实例。它们也恰好是旋转的,但我很确定这是无关紧要的。用户应该不知道该 View 是由多个 TableView 组成的。因此,我想做到当我滚动一个 tableview 时,其他 tableview 也会同时滚动。
因为 UITableView
是 UIScrollView
的子类,我想我可以处理 UIScrollViewDelegate
方法并将它们传递给所有的 tableview。不幸的是,虽然我可以捕获一些事件,但方法调用的粒度不够精细,我无法将这些消息传递给其他 TableView 。我能得到的最接近的是实现 -scrollViewDidScroll:
然后在每个 tableview 上调用 -setContentOffset:animated
。如果我尝试为所有可能的情况发送此消息,我最终会锁定,因为 -scrollViewDidScroll
正在为我的 -setContentOffset:animated
调用调用,所以我最终卡住向上。无论如何,如果我通过仅使用此方法检测一个 TableView 上的滚动然后将其传递给其他 TableView 来消除锁定,我发现虽然其他 TableView 最终滚动到同一位置,但它们落后一秒或两个。
Here's a sample project I created.
如何在不继承 UITableView
的情况下实现此行为?
最佳答案
您可以通过直接观察 contentOffset
来解决回调粒度问题。在 viewDidLoad
中,在每个需要同步的 TableView 上设置 KVO:
for(UITableView *view in self.tableViewCollection)
{
[view addObserver:self
forKeyPath:@"contentOffset"
options:NSKeyValueObservingOptionNew
context:NULL];
}
然后,当您观察变化时,暂时解除观察,更新其他 TableView 的偏移量,然后重新打开观察。
- (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];
}
这可能会变得更漂亮,但它可以传达这个想法。
关于objective-c - 同步多个 UITableView 实例的滚动位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9879138/