Note: check out Thuy's great subclass of UINavBar here:
https://stackoverflow.com/a/20720359/294884
If you're working on this problem, GTScrollNavigationBar is close to a ready-made solution to the navBar problem!
50 point bounty here, amazing there are no answers.
For example: on a 2014 iPhone, open Safari, load any web page.
Look at the iOS toolbar at the bottom.
Now move your finger up and down ONLY A FEW PIXELS.
Basically the toolbar at the bottom, moves with your finger. Furthermore, the toolbar later appears/disappears as you scroll the page, following specific logic.
But the interaction rules are very complicated, and involve finger on/off during the hide, distance matching, gestures when you are further down the page, special cases for very short pages, and so on.
I want to EXACTLY duplicate the Apple behaviour.
(It seems sensible that we should match the Apple UX.)
Is there a way to do this? does Apple offer a one-step command for that, which I don't know about? Or do you have to laboriously duplicate the concept?
Thanks.
By the way, the following logic is reliable and will roughly duplicate the way Apple does it:
-(void)feedIsScrolled:(CGFloat)scrollNewOverallYPosition
{
// call this routine when scrollViewDidScroll:
self.feedIsScrolledDelta =
scrollNewOverallYPosition - self.feedIsScrolledPrevious;
self.feedIsScrolledPrevious =
scrollNewOverallYPosition;
// nb, you do those only in this routine, NOT the following routine.
if ( scrollNewOverallYPosition < 15.0 )
{
.. animate in the bar
return;
}
if ( self.feedIsScrolledDelta > 0.0 )
.. animate away the bar
}
-(void)feedIsThrown:(CGFloat)scrollNewOverallYPosition
{
// call this routine when scrollViewDidEndDragging:
// BUT ONLY when willDecelerate: is true
if ( self.feedIsScrolledDelta <= 0.0 )
.. animate in the bar
else
.. animate away the bar
}
By the way, of course you can use
(void)setToolbarHidden:(BOOL)hidden animated:(BOOL)animated
to slide a UIToolbar up and down. BUT that does not help in any way with "finger matching".
Note: and here for example is a superb solution seen on SO:
https://stackoverflow.com/a/21049991/294884
You could program like that, implementing each and every rule in the Apple example, to suit your taste on each point. (What to do when you are near the bottom, finger up, which direction, etc etc.) My point is I just assumed someone must have done all that work already of matching the Apple UX exactly -- heh!
I used the next code to hide tabBar like in safari app. Maybe you or other people can use it with toolBar.
Create constant for base value of navigation bar origin Y position
Add your custom selector to handle system swipe gesture that will fire before navBar become hidden and during hiding
There is no open-source that does this, but I don't see it as that difficult to implement. It may be somewhat more difficult to have the exact 1:1 behavior as Safari, but it can still be done.
MobileSafar can be attached to in the debugger and, using breakpoints and the Objective C runtime, debugged and reverse engineered.
For example, your two assumptions that no toolbar and navigation bars are used are incorrect.
Here is the view hierarchy before scrolling:
http://pastebin.com/aRXr7b5Z
And after scrolling:
http://pastebin.com/CasBNuxq
As you can see, the bars have been moved from their normal location.
Breaking on
-[BrowserToolbar setFrame:]
, here is the stack trace:So it all happens after a notification of scrolling.
I put a breakpoint on
MobileSafari'___lldb_unnamed_function990$$MobileSafari
and to get theself
variable, printpo $arg1
. This is where all the magic happens:http://pastebin.com/kjAXKKTW
If you are really interested in 1:1 replication, you can put breakpoints on these methods and investigate. Good luck!
I just pulled a request to GTScrollNavigationBar that helps getting the right "match finger movement". The trick is just to adjust ContentInsets according to scrollbar's frame.
It's probably not yet perfect, but it does what you look for: https://github.com/luugiathuy/GTScrollNavigationBar/pull/21