I know there's tons of code out there to scroll a tableview to the top, but I want to do this when the top status bar is tapped, just like in Apple's native apps. Is this possible?
-
1I tested (iOS 8) and found that item "3" from [Zane Claes checklist](http://stackoverflow.com/questions/7165913/scroll-to-top-of-uitableview-by-tapping-status-bar/15930310#15930310) is not necessary. – Marcio Fonseca Oct 27 '14 at 14:45
9 Answers
You get this for free, but you should check that the scrollsToTop
attribute of your UITableView
is YES.
When this does NOT work is when you have a UIScrollView
(or descendant class like UITextView) object embedded inside another UIScrollView
class (like UITableView
). In this case, set scrollsToTop
on the embedded UIScrollView
class to NO. Then the tap-the-status-bar behavior will work.

- 38,547
- 26
- 130
- 141

- 16,878
- 2
- 59
- 61
-
8I've tried what you suggest – setting the embedded scrollview's scrollsToTop to NO – but the status bar tap still doesn't cause the top scrollview to scroll to the top. – CharlieMezak Oct 20 '11 at 22:56
-
3This works perfectly. @CharlieMezak perhaps you have more than one embedded scroll view onscreen. They must all be set to NO apart from the scroll view at the top of the view hierarchy. – imnk Apr 16 '13 at 13:23
-
4In my case I had some horizontally scrolling collection views within my vertically scrolling table view, setting `scrollsToTop` to `NO` for all of the collection views worked. Seems unintuitive but it worked! – Chris Wagner Oct 03 '13 at 03:19
-
5@CharlieMezak note that `scrollsToTop = NO` rule must be applied to all views within a __window__. For example, in case when you have side menu. – vokilam Oct 31 '13 at 12:27
-
Thank you! This helped me also. Setting scrollsToTop = YES to my tableview and to my customTableViewCell's TextView, I set it to NO. – JCurativo Feb 17 '14 at 01:24
-
1This was occurring in my UICollectionView. I had a side-scrolling UIScrollView within each UICollectionViewCell. Setting scrollsToTop = NO to the cell's scrollView fixed the issue. Thanks – RyanG Oct 17 '14 at 13:06
-
-
This has stopped working for iOS9. Can you give me a hack for this. – Faisal Shaikh Jun 09 '16 at 06:14
-
Oh, I think not, @FaisalShaikh. I suggest reading the documentation for `scrollsToTop` carefully. Make sure only the scroll view (or descendent) class you want to scroll to top when the status bar is tapped has `scrollsToTop` set to `YES`. Any other scroll views embedded in your main scroll view should have `scrollsToTop` set to `NO`. If more than one scroll view has `scrollsToTop` set to `YES`, then the gesture is ignored. – Mark Granoff Jun 09 '16 at 12:38
-
In my screen, status bar is hidden. Is there any workaround to achieve this? – AsifHabib Nov 03 '16 at 09:10
-
@AsifHabib I think you would have to implement your own tap gesture recognizer in the view that is visible to detect a touch at the top of the screen and then in code cause your content to scroll to the top. – Mark Granoff Nov 03 '16 at 13:22
If you came from Google and need a complete checklist:
- Check that you've set scrollsToTop=YES (per Mark's suggestion) on your UITableView
- Make sure that you've set scrollsToTop=NO on all OTHER UITableViews / UIScrollViews / UITextViews in your window, so that they're not intercepting the click. I've found myself printing out all the views in my window many times to debug this...
- Make sure that your table view is at 0/0 (x/y coordinates) within the window - this is how the system knows that it should pass the message

- 38,547
- 26
- 130
- 141

- 14,732
- 15
- 74
- 131
-
8What if it's in a child view controller that puts it below 0,0 within the window? – shim Jun 28 '13 at 00:18
-
This was useful when you use multiple uiwebviews as you need to set non active webviews' scrollstotop properties to NO – Matthew Hui Jul 12 '13 at 19:39
-
Thank you for this complete checklist. Searched my code for UITextView and found the one causing issues. – werm098 Mar 18 '14 at 11:59
-
2As @shim asked - @Zane/@Kyle - what if it's in a child view controller that puts it below 0,0 within the window? – ofer2980 Oct 04 '15 at 11:09
Using the information given in other answers, I added the following code to my UITableViewController get it to work:
- (void)viewDidLoad { [super viewDidLoad]; for (UITextView *view in self.view.subviews) { if ([view isKindOfClass:[UITextView class]]) { view.scrollsToTop = NO; } } self.tableView.scrollsToTop = YES; }
This looks through all the views in the UITableViewController's hierarchy and turns off scrollsToTop on all the UITextViews that were intercepting the touch event. Then, ensured the tableView was still going to receive the touch.
You can mod this to iterate through other UITableViews / UIScrollViews / UITextViews that may be intercepting as well.
Hope this helps!

- 149
- 2
- 3
-
Actually you could just change UITextView to UIScrollView in your code and it would catch all UITableViews and UITextViews since they are both subclasses of UIScrollView. – bdmontz Jun 15 '15 at 18:07
I had the same problem but fixed by following steps:
- Set scrollsToTop = YES for tableview you wanted to scroll to top.
- set scrollsToTop = NO for all other tableview or collection view or scrollview.
- If any of your tableview cell has collection view . Make sure you set scrollsToTop to NO for the collection view as well.
If your view controller/ navigation controller is added as a subview on another view controller, Make sure you set it as a child Controller.

- 61
- 1
- 2
I know this is quite an old one but hope this can help. Following what @MarkGranoff said, the scrollsToTop doesn't work if more than one UIScrollView, or its subclasses, has got it set to YES (default value), a sanity check is probably worth to check who's actually messing up with this behaviour. The simple method below loop over the subviews of your view and logs the scrollsToTop value of all the UIScrollView in your view. Preferably to be called in your viewDidAppear method.
- (void)checkForScrollViewInView:(UIView *)view {
for (UIView *subview in [view subviews]) {
if ([subview isKindOfClass:[UIScrollView class]]) {
NSLog(@"scrollsToTop enabled: %i in scroll view %@", ((UIScrollView *)subview).scrollsToTop, subview);
}
if (subview.subviews.count > 0) {
[self checkForScrollViewInView:subview];
}
}
}
This is just a debug code indeed. Once you find the scrollsToTop value for each one of the UIScrollView subclasses just make sure only one is set to YES.

- 313
- 2
- 4
Like Mark said, you can only have one subclass of UIScrollView (usually the table view) that has the scrollsToTop property set to TRUE. Likely you have others, typically UITextView in your view. Just set their scrollsToTop property to FALSE and you're good to go.

- 2,187
- 2
- 17
- 11
-
This was my issue, I had 2 table views on the same screen, each with an outlet so simply setting one to false did the trick for me, thanks! – Stu P. Nov 17 '15 at 20:25
On UIScrollView header file:
// When the user taps the status bar, the scroll view beneath the touch which is closest to the status bar will be scrolled to top, but only if its
scrollsToTop
property is YES, its delegate does not return NO fromshouldScrollViewScrollToTop
, and it is not already at the top. // On iPhone, we execute this gesture only if there's one on-screen scroll view withscrollsToTop
== YES. If more than one is found, none will be scrolled.

- 51
- 4
For example if you have a table view and scroll view like tags like this
you should make something like this in viewDidLoad
self.tableView.scrollsToTop = true
self.tagsView.scrollsToTop = false

- 2,872
- 1
- 36
- 32
There can be multiple UIScrollView descendants loaded eg.: having a UIPageViewcontroller on each page containing UITableViews.
The scrollsToTop property is true by default.
So in addition to handling nested UIScrollViews' scrollsToTop property, you should do the following:
//When the view is loaded disable scrollsToTop, this view may not be the visible one
override func viewDidLoad() {
super.viewDidLoad()
...
tableView.scrollsToTop = false
}
//Now it's time to enable scrolling, the view is guaranteed to be visible
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
tableView.scrollsToTop = true
}
//Do not forget to disable scrollsToTop, making other visible UIScrollView descendant be able to be scrolled to top
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.tableView.scrollsToTop = false
}
This way only one top level UITableView's scrollsToTop will be set to true.

- 81
- 1
- 6