When I am navigating back & forth between parent and child controllers in a master - detail navigation controller, i see a dark shadow on the right side of navigation ba
self.navigationController.navigationBar.translucent = NO;
For Newer Swift Versions:
navigationController?.navigationBar.isTranslucent = false
nonamelive's answer is perfect. To achieve the same thing in Interface Builder AND STILL KEEP TRANSLUCENCY, select the navigation controller and set a user defined runtime attribute view.backgroundColor
as shown in the screenshot (in the Identity Inspector). Repeat for all navigation controllers that show this problem.
It seems that this whole problem occurs because the black color (or actually, no color) of UINavigationController is leaking through at the time CoreGraphics snapshots it at animation begin. So, setting it to white will prevent that.
self.navigationController.view.backgroundColor = [UIColor whiteColor];
I solved this problem by setting the background color of the navigation controller's view.
This seems to be a bug that was introduced in iOS 7.1. In my case it is caused by a UIToolbar placed directly below the navigation bar. The dark shadow also appears in the translucent tab bar.
The shadow seems to be caused by the background view of the UIToolbar. I now use this workaround in the view controller with the toolbar that hides the toolbar's background view during the transition:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
UIView *toolbarBackgroundView = [self.toolbar findViewRecursively:^BOOL(UIView *subview, BOOL *stop) {
BOOL isToolbarBackgroundView = ([subview isKindOfClass:[UIImageView class]]
&& [NSStringFromClass(subview.class) isEqualToString:@"_UIToolbarBackground"]);
if (isToolbarBackgroundView) {
*stop = YES;
}
return (! isToolbarBackgroundView);
}];
if (toolbarBackgroundView) {
// fade toolbar background view back in
[UIView animateWithDuration:0.1f animations:^{
toolbarBackgroundView.alpha = 1.0f;
}];
}
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
UIView *toolbarBackgroundView = [self.toolbar findViewRecursively:^BOOL(UIView *subview, BOOL *stop) {
BOOL isToolbarBackgroundView = ([subview isKindOfClass:[UIImageView class]]
&& [NSStringFromClass(subview.class) isEqualToString:@"_UIToolbarBackground"]);
if (isToolbarBackgroundView) {
*stop = YES;
}
return (! isToolbarBackgroundView);
}];
if (toolbarBackgroundView) {
// hide toolbar background view
toolbarBackgroundView.alpha = 0.0f;
}
}
This is the code for [UIView findViewRecursively:]
@interface UIView (FindSubview)
- (UIView*)findViewRecursively:(BOOL(^)(UIView* subview, BOOL* stop))recurse;
@end
@implementation UIView (FindSubview)
- (UIView*)findViewRecursively:(BOOL(^)(UIView* subview, BOOL* stop))recurse {
for (UIView* subview in self.subviews) {
BOOL stop = NO;
if (recurse(subview, &stop)) {
UIView* view = [subview findViewRecursively:recurse];
if (view) return view;
} else if (stop) {
return subview;
}
}
return nil;
}
@end
I filed this Radar: http://openradar.appspot.com/16418845
This works for me in Swift
In AppDelegate
on didFinishLaunchingWithOptions
method, I set this:
UIApplication.shared.windows.first?.backgroundColor = .white
Here is my variation...it requires much less code than tom's answer, and is more efficient. This is IF you want a translucent navigation bar, and also want to fix that shadow problem.
In the source ViewController (that is embedded in the Navigation Controller)...
- (void)viewDidAppear:(BOOL)animated
{
self.navigationController.navigationBar.translucent = YES;
}
and
- (void)viewWillDisappear:(BOOL)animated
{
self.navigationController.navigationBar.translucent = NO;
}
The result is the same as what Tom does (visually, to the end user), and is easier to implement. Hope this helps...