In my app, I have two tableViews side by side. When the user scrolls on, I would like the second one to scroll at the same time, so it looks almost like one table with two d
You'll want to look into the UIScrollViewDelegate
- say you've got two scroll views, A and B.
Use the scrollViewDidScroll
delegate method of scroll view A to get the offset, and then in the same method call setContentOffset
on scroll view B, passing in the value you get from the delegate.
It actually shouldn't be more than 2-3 lines of code once you've set-up your delegate methods.
Conveniently, UITableView is a subclass of UIScrollView. There exists a UIScrollViewDelegate, which has this method:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
If you implement that method, you can get the contentOffset
property of the scrollView
argument. Then, you should use
- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated
and set the new content offset. So something like this:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
UIScrollView *otherScrollView = (scrollView == self.tableView1) ? self.tableView2 : self.tableView1;
[otherScrollView setContentOffset:[scrollView contentOffset] animated:NO];
}
You can cast to a UITableView if you'd like, but there's no particular reason to do so.
UITableView is a subclass of UIScrollView. Swift solution:
extension yourViewController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let otherScrollView = (scrollView == tableViewLeft) ? tableViewRight : tableViewLeft
otherScrollView?.setContentOffset(scrollView.contentOffset, animated: false)
}
}
And stop the bounce of both the tables
tableViewLeft.bounces = false
tableViewRight.bounces = false
If you want to make vertical scroll Indicators go, write the below code
tableViewLeft.showsVerticalScrollIndicator = false
tableViewRight.showsVerticalScrollIndicator = false
in swift scroll two uitableviews symmetrically:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if tb_time1 == scrollView {
tb_time2.contentOffset = tb_time1.contentOffset
}else if tb_time2 == scrollView {
tb_time1.contentOffset = tb_time2.contentOffset
}
}
also, the tableview that got scrolled by the user should not be sent setContentOffset: message in scrollViewDidScroll, since it will get the app into endless cycle. so additional UIScrollViewDelegate methods should be implemented in order to solve the problem:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
beingScrolled_ = nil;
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
if(beingScrolled_ == nil)
beingScrolled_ = scrollView;
}
and modifying Inspire48's version scrollViewDidScroll: accordingly:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
UIScrollView *otherScrollView = (scrollView == self.tableView1) ? self.tableView2 : self.tableView1;
if(otherScrollView != beingScrolled)
{
[otherScrollView setContentOffset:[scrollView contentOffset] animated:NO];
}
}
where beingScrolled_ is an ivar of type UIScrollView