Transitioning between transparent navigation bar to translucent - ios

In Apple's recently released Remote app I noticed the way in which the navigation bar behaves is unique and I haven't been able reproduce it. When popping the Now Playing view controller the navigation bar remains transparent for the Now Playing view controller and the navigation bar for the library view controller also stays translucent (Screenshot 1). I'm trying to figure out if they are using two navigation controllers or only one. Personally I feel they're using just one for two reasons (1) the interactive pop gesture is enabled; (2) when you press the 'Now Playing' button in the library view controller, just before the now playing screen has finished 'push view controller' animation the navigation bar becomes transparent (Screenshot 2). This is the behaviour I experience when pushing my view controller (which sets the navigation bar to transparent). So my question is: How does Apple present both navigation bars of the two view controllers as if they were individual (as with Screenshot 1), even the bar buttons, navigation title etc... are 100% in opacity when switching (usually when pushing/popping the buttons and titles of the previous view controller fade as the new controller is being pushed). I've tried playing around with the bar tint colour in viewDidAppear and viewWillAppear in both view controllers but cannot reproduce the same behaviour, and cannot prevent the bar buttons from fading.
Gosh I hope I've explained this well, I get confused just thinking about it!
Screenshot 1 (Popping):
Screenshot 2 (Pushing):

I just downloaded the application to make sure. Two different navigation bars are used. You can see this by using the interactive pop gesture. Notice how the navigation bar on the bottom view controller slides in and out. During normal push and pop transitions, the navigation items just fade in and out on the existing bar, while the bar is stationary. This is what happens up until the point where the now playing view controller is pushed.
If you look quickly, during the now playing view controller animation, you can see the bottom navigation bar disappear.
From my experience with UIKit behavior and what I see in the app, here is what I think happens:
album_vc = the bottom, list view controller
nowplaying_vc = the top view controller
On nowplaying_vc's viewWillAppear:
Set the navigation bar to hidden using [self.navigationController setNavigationBarHidden:YES animated:YES];. Since this is in animation block, this will make the navigation bar slide out during the push animation.
Set [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent; Pretty sure about this, because notice there is no animation in the transition of the status bar styles. It just becomes white.
On nowplaying_vc's viewWillDisappear:
Set the navigation bar to shown using [self.navigationController setNavigationBarHidden:NO animated:YES];. Since this is in animation block, this will make the navigation bar slide in during the pop animation.
Set [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault; Again, notice how during interactive pop gesture, the status bar just changes with no animation.
To achieve the transparent look of the navigation bar of nowplaying_vc, you can use an empty image ([UIImage alloc]) with setBackgroundImage:forBarPosition:barMetrics:.
Since the application does not rotate, we can't be sure if the navigation bar on nowplaying_vc is part of another navigation controller or just a navigation bar on the top with a position of UIBarPositionTopAttached. For all we know, there isn't even a navigation bar there but just a back chevron image view (back bar button is comprised of an image view and a button).
I think the status bar style is changed in viewWillAppear: and viewWillDisappear: due to the unnatural feel there is during interactive pop gesture. I would recommend using an animated transition, or even better, use the new view controller-based status bar style, which the system animates transitions by itself.
Update for modern API:
You should use the animateAlongsideTransition:completion: or animateAlongsideTransitionInView:animation:completion: API, rather than relying on the implicit animations of viewWillAppear: and viewWillDisappear:.

Instead of hiding and showing the navigation bar, you can update the alpha for the navigation bar. It will animate smoothly during the transition. For the view controller with transparent nav bar, instead of modifying the nav bar, create a navbar (or just the back button and title etc.) manually in the second controller's view. We will then hide the navbar when transitioning from first view controller to the second one.
On your first controller's viewWillDisappear and on your second view controller's viewWillAppear:, set the navigation bar alpha to zero using self.navigationController.navigationBar.alpha = 0;. Since this is in animation block, this will make the navigation bar disappear during the push animation.
Set the alpha back to one in first controller's viewWillAppear and second controller viewWillDisappear.

Related

How can I ensure iOS 13 modal view controllers present the right status bar colour?

With the new iOS 13 view controller changes, view controllers are being presented that don't cover the whole screen. They instead leave a black space at the top. However, the system status bar is not changing colour automatically. When I present a modal view controller, the status bar is staying with now-invisible black text (and a green battery which looks super weird in the middle of nowhere).
How do I make the bar behave in the same way as within Apple's apps, where the bar animates to different colour when a modal popup appears?
I've tried setting modalPresentationCapturesStatusBarAppearance to true on my modal controllers, to no luck.
The bar in my presenting view controller is a UINavigationBar, and is not part of a navigation controller. The presenting VC is its delegate, and I've overridden position(for bar: UIBarPositioning) to return .topAttached.
I've tried presenting the modal with .modalPresentationStyle = .formSheet and without setting .modalPresentationStyle at all. Neither worked.
Broken:
The presenting VC:
Expected Behaviour:
Two things:
The modal view controllers need to have VC.modalPresentationCapturesStatusBarAppearance = false. This is the default but if, like me, you set it to something else, make sure it's false!
You need to ensure that View controller-based status bar appearance in your info.plist is set to YES. I'd messed around with it in an attempt to make my status bar the right colour but having it set to NO was a problem.

iOS UINavigationController push/pop cross horizontal cover animation

The pushed controller cross over current controller.
Results are as follows:
image 0
Actually, I have hook into this app, it use a subclass named MMUINavigationController,
and I am sure current action is "pushViewController:animated:", it's the interface I hooked.
Tweak.xm:
image 1
alertView:
image 2
how to make it ?
additional,standar animation:
image 3
navigation bar of pushed controller
image 4
Here's one solution:
hide the navigation bar of the navigation controller
add a navigation bar to the root view controller of the navigation controller
restore the swipe to back gesture to the navigation controller
For the last point you can add a pan gesture recognizer (suggested) or simply set the interactivePopGestureRecognizer's delegate of the navigation controller to nil:
self.navigationController?.interactivePopGestureRecognizer?.delegate = nil;
but please refer to this discussion for its implications: No Swipe Back when hiding Navigation Bar in UINavigationController
EDIT:
Working solution which fulfills the requirements: just setting the navigationBarHidden in the viewWillAppear does the magic.
I've setup a sample demo here: https://github.com/ldantona/NavigationBarExample
EDIT 2:
Just found this library, could it be of any help?
https://github.com/MoZhouqi/KMNavigationBarTransition
The library can capture the background style of the navigation bar in
the disappearing view controller when pushing, and when you pop back
to the view controller, the navigation bar will restore the previous
style, so you don't need to consider the background style after
popping. And you also don't need to consider it after pushing, because
it is the view controller to be pushed that needs to be considered.
Hope it helps

present modal view hides the navigation bar in navigation stack

I have spent hours on this wired problem.
The scenario is I have push a new chatting view controller to the root navigation controller.
Then I customized the navigation bar item in the viewdidload method.
Everything works fine.
Then I present a image picker view which enables the image upload function.
And dismiss that picker view, which was presented as modal view.
After the picker view dismissed, the customized left navigation bar button disappeared.
The navigation bar appearance is the same as the root navigation bar but not the customized appearance is the current view controller.
Because the some pieces of the work includes the third party SDK, so I am not able to directly change the UIPickerView in order to detect the dismiss event and change the navigation bar appearance.
Can anyone helps? Thank you so much.
You should removed customised the navigation bar item on viewWillDisappear and add this viewWillAppear instead of viewDidLoad

iOS7 Keep UINavigationBar and animate only the view on segue

There is one thing i thinking about for days now. I want to keep the same navigation bar on every viewcontroller in my app (like in the amazon app) and show the push animation (push segue) only on the view itself without touching the nav bar.
Is there a simple way to do that?
If both of the views are inside the same UINavigationController, then the nav bar will not be changed at all when you use the push segue. If you don't want any nav bar title animations, etc just set the same title/buttons on the next view, and it will look like nothing changed. When the new view controller is pushed, the nav bar will remain the same, and only what's under it will change.

How to push entire view in iOS including navigation bar and toolbar

I have 3 views connected together via a navigation controller. The middle view (#2) has special styling in that the navigation bar and toolbar are completely white to blend in with the white background.
When swiping to/from view 2 the navigation and toolbar transition is animated (as is the default) to slowly fade in the buttons and styling of the view being pushed/popped i.e. the navigation bar and toolbar remain visible during the transition.
This ends up not looking to great because of the white navigation bar and toolbar of view 2.
What I would like to achieve instead is to have each view pushed/popped in entirety i.e. including its navigation bar and toolbar. In other words, instead of the navigation bar and toolbar to persist during the transition, I would like them to slide in/out with the view they are part of.
I have attached screenshots of the 2 variants.
Would it be best to scrap the navigation controller and set up each view with its own navigation bar and toolbar? Or can this be achieved easily for my current setup.
It would be great if someone could point me in the right direction.
This is from the Apple Remote app showing the effect I would like to create.
This is from the Apple Mail app showing the default transition effect.
Use custom transitions between view controllers will give you a better effect than animating UIView's, though you can add physics behaviors to UIView objects to make it more interesting.
Apple uses interactive custom transitions (just look that up) for its own apps. Here is a good article about that too:
http://www.doubleencore.com/2013/09/ios-7-custom-transitions/
Create your view with the desired screen with navigation bar & tollbar.
On the action bring the view 2 or remove with the animation your want using view animation.
[UIView animateWithDuration:0.2
animations:^{set your fram(0,0,320,480/568) or (320,0,320,480/568)}
completion:^(BOOL finished){
}];
You can add the view to keywindow.
Hope this will help you.
Why don't you simply use the hidesBottomBarWhenPushed property over the destination view controller?
// hide the bottom tabbar when we push this view controller
destinationViewController.hidesBottomBarWhenPushed = YES;

Resources