For weeks I've been scouring resources and searching for non-kiddo dev advice about making a custom-sized UIToolbar work in a UINavigationController-based app. By "work" I mean a non-hackish approach that allows key things like graceful hide/show of the toolbar, swipe-to-hide, and other graceful animations.
Making a custom UIToolbar
class instance that goes inside the UINavigationController
instance that overrides sizeThatFits:
changes the size as expected, but there's a couple unacceptable issues as a result.
So, here we have the common sizeThatFits:
replacement offered by many:
- (CGSize) sizeThatFits:(CGSize)inSize {
CGSize sz = [super sizeThatFits:inSize];
sz.height = SS_TOOLBAR_HEIGHT;
return sz;
}
Ok, great, the size is altered, but if you set breakpoints on that function, it's clear that something else is still banging away for that ol 44 pt height. Try setting a breakpoint there and see how often it gets called -- seems fishy (this will come into play later).
Ok, fine, it changes the height as we like, so we move onto adding functionality so that the toolbar hides (w/ animation) on a touch or swipe. Well, if we enable UINavigationController's hidesBarsOnSwipe
, then there's two problems: the nav bar is tethered to the hiding (yuck), and the toolbar gets completely hidden so that brining it back is totally non-WYSIWYG. Our design goal is to get the toolbar operating like a drawer that slides in/out on the appropriate swipe direction, independent of the nav bar. Further rather than hiding the toolbar completely, we'd like to have a lil stub/tab thing maybe 10-20 pts tall that indicates the user can slide the toolbar back upward like a drawer back to its normal state.
So to do this, we alter sizeThatFits:
in our UIToolbar derived class:
- (CGSize) sizeThatFits:(CGSize)inSize {
CGSize sz = [super sizeThatFits:inSize];
sz.height = _minimized ? SS_TOOLBAR_HEIGHT_MINIMIZED : SS_TOOLBAR_HEIGHT;
return sz;
}
On a minimize state change we would naturally hide/show the appropriate subviews so it would appear normally or be, say, 15 pts high with a little grip-graphic ditty. So the major issue with this approach is that now any attempts at toolbar animation to slide it in/out get totally b0rked thanks to sizeThatFits:
getting called during animation and short-circuiting it. Ok Apple, fine, let's try hacks like setting the destination size elsewhere with:
- (CGSize) sizeThatFits:(CGSize)inSize {
CGSize sz = [super sizeThatFits:inSize];
if ( _animationInProgress ) {
sz.height = _minimized ? SS_TOOLBAR_HEIGHT_MINIMIZED : SS_TOOLBAR_HEIGHT;
}
return sz;
}
Well things just snowball at this point into insanity. Calls to sizeThatFits:
abound and attempts at drawer-like hide/show animation look even more broken as the 44 pt ghost size wins out, dorking everything up.
So, in short, I'm looking a pro dev to share info/suggestions on how to proceed with using a UINavigationController but having a toolbar with well-behaved animated drawer-like behavior. I'll settle for almost anything at this point, just that the "minimized" state is WYSIWYG-friendly so the user can get the toolbar back. Maybe one approach is to make a tiny floating UIView that sits at the bottom and is shown only when the toolbar is hidden (and when touched or swiped, the toolbar would be unhidden and animation would be fluid). How and where would I persist such a "floating" view?
I guess what gets me about all this and why I feel like I'm posting for help in exasperation is that the needed toolbar functionality discussed here seems like functionality most iOS developers would absolutely welcome and would see as a major improvement to UINavigationController+UIToolbar's current limitations.
I have decent experience in iOS, but I'm a OS X and Win vet of maaaany moons, so help from other pro devs is HIGHLY appreciated.
Thanks in advance!