13

I'm trying to structure a page similar to Twitter's profile page. It looks like they are using a basic UITableView. The top profile is just the tableHeaderView. The tabs are a UISegmentedControl inside the SectionRowHeader so that it sticks to the top when scrolled. And the tweets are just the cells inside that section. And if you switch tabs, it seems like they are simply changing the underlying data and reloading the table.

However if you play with the page, you'll notice that changing tabs keeps the previous scroll position. And if you scroll back to the top on one tab, then of course the other tab has to be scrolled to the top otherwise it'll be scrolled underneath the header. Also, if you look closely the bottom part (the tweets) has its own scrollbar once you start scrolling. So it seems like that is its own tableview. So would that be a new tableview inside the cell of the main page? And if that's what they're doing, then the scrolling is seamless between them. You're able to scroll the bottom part up and only once the tabs are pinned to the top do the tweets scroll underneath it.

I'm trying to build a similar structured page but keep running into issues. Ideally I would also like to have the logic of those sub tabs broken out into separate view controllers for reuse but at this point I would just like to get this working.

Anyone have any idea of the structure they're using to setup a page like this?

Oren
  • 5,055
  • 3
  • 34
  • 52
  • Scroll view within a scroll view? Try to go through this http://oleb.net/blog/2014/05/scrollviews-inside-scrollviews/ – rounak Jul 03 '15 at 18:30
  • But a scrollview can't have a section header that sticks to the top. So unless they're manually building that logic, it's a tableview with an innerscrollview. But I point out the problem with that above (doesn't scroll seamlessly, etc) – Oren Jul 03 '15 at 18:33
  • @Oren did you able to figured it out yet? – kidsid49 Nov 24 '15 at 11:15
  • unfortunately not. my guess is they built something very custom to get this basic functionality. Upvote so maybe someone will find it and answer. – Oren Nov 24 '15 at 15:28
  • I want to do some similar dude, did you found the answer?....Actually i just want to have a header touchable... – Dasoga Dec 28 '15 at 16:52
  • nope my best guess is they built something very custom. to have the header touchable though you can just put a button inside the tableviewheader or a touchevent. it's the multi-tabs and scrolling which is unique here. – Oren Dec 28 '15 at 17:48
  • I think it's using a CollectionReusableView – Victor Rius Feb 02 '17 at 15:40
  • I tried to explain a bit [here](https://stackoverflow.com/a/57649852/5923606). – ugur Aug 25 '19 at 21:39

2 Answers2

1

I'm 99% certain they are simply adjusting the scroll indicator insets as you scroll view the table:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat const visibleHeaderHeight = 0.0; // your logic here
    UIEdgeInsets const insets = UIEdgeInsetsMake(visibleHeaderHeight, 0.0, 0.0, 0.0);

    self.scrollView. scrollIndicatorInsets = insets;
}

Also I'm pretty sure they are using a grouped style table view due to the sectioning, so you would need to build the sticky header yourself. You can also do that in -scrollViewDidScroll: though.


If you want to break the tabs into separate view controllers, I would recommend the following setup:

  • have a container view controller managing the header view containing the tabs
  • use UIViewController containment to plug in the active view controller
  • subscribe to the active view controller's scroll view's contentOffset and adjust the scroll indicator inset and sticky header y position accordingly
Christian Schnorr
  • 10,768
  • 8
  • 48
  • 83
  • If they're just setting the insets though, how do they pass the scroll and velocity from one scrollview to the next? Try scrolling the top header part fast. You'll notice is scrolls and then as soon as the tabs get stuck the bottom part continues scrolling. It acts as if it's a single scrollview. – Oren Jul 05 '15 at 21:17
  • They only have one scroll view, and reposition the header on scroll event to make it look sticky. – Christian Schnorr Jul 05 '15 at 21:32
  • I tried this setup as well and the problem with having only one scrollview and pushing the tweets down with the content inset is that the header will either be behind the scrollview (and therefore not clickable) or above it (and would therefore interfere with scrolling gestures). If it's a single tableview though, I don't think each individual tab's scroll position would be maintained so would they be manually persisting that info? This approach would also make this page extremely complex and hard to maintain I think. – Oren Jul 05 '15 at 21:50
  • @Oren You can have the container manage the header view, but 'plug' it into its child view controller's view hierarchy. This way it can be a *subview* of a child view controller and user interaction should work fine. Then the child view controller would be responsible to make the header stick to the top while it scrolls. – Christian Schnorr Jul 05 '15 at 23:58
  • For what it's worth, they're definitely not just setting the scroll indicators. You can tell because if you pull the table down, the scroll indicators never go higher than the tabs. If the entire page was a single scrollview with indicators adjusted, then they'd bounce above the tabs. – Oren Apr 22 '16 at 02:27
  • They are manually setting the scroll indicators. The whole point of manually setting those is that you can have the scroll view fullscreen and have them inset to where you want them... – Christian Schnorr Apr 26 '16 at 16:17
0

I tried to explain a bit here.

After a long long investigation that is how i achieve the twitter profile behaviour.

  • UnderlayScrollView
  • MasterScrollView
    • Header ViewController
    • Bottom ViewController
      • PagerTabItems [CollectionView]
      • UIPagerController or any other horizontal scroll (Parchment, XLPagerTabStrip).

UnderlayScrollView is responsible of controlling the scroll gesture. its contentoffset is used to adjust inner scroll contentOffsets. Contentsize of the underlaying scroll is same as the masterscroll's contentsize.

See the source code on github for more. click

ugur
  • 3,604
  • 3
  • 26
  • 57