In the new iOS7 Facebook iPhone app, when the user scrolls up the navigationBar
gradually hides itself to a point where it completely vanishes. Then when the user scrolls down the navigationBar
gradually shows itself.
How would you implement this behavior yourself? I am aware of the following solution but it disappears right away and it isn't tied to the speed of the user's scroll gesture at all.
[navigationController setNavigationBarHidden: YES animated:YES];
I hope this isn't a duplicate as I'm not sure how best to describe the "expanding/contracting" behavior.
I tried implementing GTScrollNavigationBar but my app required me to modify auto layout constraints. I decided to put an example of my implementation up on GitHub in case anyone else has to do this with auto layout. The other issue I had with most of the other implementations is that people don't set the bounds of the scroll view to avoid the parallax scrolling effect that you create while you scroll and adjust the size of the scrollview simultaneously.
Check out JSCollapsingNavBarViewController if you need to do this with auto layout. I've included two versions, one with the nav bar only and another with a sub-bar below the nav bar which collapses before collapsing the nav bar.
I was looking for a solution that allowed for any style and any behavior. You'll notice that bar condensing behavior is different in many different apps. And of course, the way the bar looks is totally different between apps.
I created a solution for this issue with https://github.com/bryankeller/BLKFlexibleHeightBar/
You can definine your own behavior rules to control how and when the bar shrinks and grows, and you can define exactly how you want the bar's subviews to react to the bar condensing or growing.
Have a look at my project if you want a lot of flexibility to make whatever kind of header bar you can think up.
Here is one more implementation: TLYShyNavBar v1.0.0 released!
I decided to make my own after trying the solutions provided, and to me, they were either performing poorly, had a a high barrier of entry and boiler plate code, or lacked the extension view beneath the navbar. To use this component, all you have to do is:
Oh, and it is battle tested in our own app.
I was trying to emulate this behavior in a situation where I needed a customized header sitting about a UITableView. I rolled my own "navigation" bar because this sits below a bunch of other stuff on the page and I wanted the section headers to follow the default "docking" behavior. I think I found a pretty clever and succinct way to adjust a UITableView/UIScrollView together with another object in a style similar to that seen in the Facebook/Instagram/Chrome/etc. apps.
In my .xib file, I have my components loaded into a freeform view: http://imgur.com/0z9yebJ (sorry, don't have the rep to inline images)
Notice that, in the left sidebar, the table is ordered behind the main header view. You can't tell from the screenshot, but it also has the same y position as the main header view. Since it extends out of sight, the contentInset property on the UITableView set to 76 (the height of the main header view).
To make the main header view slide up in unison with the UIScrollView, I use the UIScrollViewDelegate's scrollViewDidScroll methods to perform some calculations and change the UIScrollView's contentInset as well as the main header view's frame.
The first if statement does most of the heavy lifting, but I had to include the other two to handle situations where the user is dragging forcefully and the initial contentOffset values sent to scrollViewDidScroll are outside of the range of the first if statement.
Ultimately, this is working really well for me. I hate loading up my projects with a bunch of bloated subclasses. I can't speak to whether this is the best solution performance-wise (I've always been hesitant to put any code in scrollViewDidScroll since it gets called all the time), but the code footprint is the smallest I've seen in any solution for this problem and it doesn't involve nesting a UITableView in a UIScrollView (Apple advises against this in the documentation and touch events end up a bit funky on the UITableView). Hope this helps someone!
Here is my implementation: SherginScrollableNavigationBar.
In my approach I am using
KVO
for observingUIScrollView
's state, so there is no necessity to use a delegate (and you can use this delegate for whatever else you need).This works for iOS 8 and above and ensures that the status bar still retains its background
And if you want to show the nav bar when you tap on the status bar you can do this: