升级到Xcode 5.1和iOS 7.1后的转换过渡期间导航栏上的暗影


91

当我在主/详细导航控制器中的父控制器和子控制器之间来回导航时,我在顶部导航栏的右侧看到一个黑色阴影。它是在我升级到Xcode 5.1之后开始的。感觉粗糙且分散注意力。我该如何摆脱呢?

Answers:


143
self.navigationController.view.backgroundColor = [UIColor whiteColor];

我通过设置导航控制器视图的背景色解决了这个问题。


这个答案实际上是非常好的。由于某些原因,Interface Builder不允许您访问导航控制器的视图,但是看起来darkColor视图仍然存在并导致此问题。
superarts.org 2015年

1
这是一个很好的答案,因为它还允许条形图保持半透明,而不会显示从导航控制器渗出的难看的黑色部分。只希望有一种方法可以在情节提要中进行设置。
dimiguel

究竟。我不时考虑它,并对建议关闭导航栏透明度的其他答案感到有些失望,因为基本上他们是通过禁用功能来解决此问题的,而该功能指出了实际的解决方法。太糟糕了,这种行为仍然是相同的在Xcode 7/9的iOS
superarts.org

1
抱歉,我否决了这个答案,因为窗口背景不是此问题的根本原因。请查看附件中的屏幕截图:imgur.com/a/SH5Dp您会发现问题仍然存在,深色阴影已替换为白色阴影,我想细节控制器已“卡住”或以某种方式使其无法在NavBar下绘制任何内容。
mariotaku '16

1
如果根控制器是UITabBarController,则tabBarController?.view.backgroundColor = UIColor.white。
维沙尔·辛格

53
self.navigationController.navigationBar.translucent = NO; 

解决它


你把它放在哪里?
Zorayr 2014年

在主视图控制器的ViewDidLoad方法中
Nihat

在viewDidAppear中添加
Abdul Waheed

我认为这实际上是正确的答案。在navigationController.view.backgroundColor = .white没有了在iOS 11.工作
AnBisw

1
@Annjawn,navigationController.view.backgroundColor = .white可在iOS 12上使用。在需要导航的情况下,不能使用从导航栏中删除半透明的按钮,但是不需要黑色阴影。
Alex Motor

38

nonamelive的答案是完美的。要在Interface Builder中实现相同目的并保持TRANSLUCENCY,请选择导航控制器并设置用户定义的运行时属性view.backgroundColor,如屏幕快照(在Identity Inspector中)所示。对所有显示此问题的导航控制器重复上述步骤。

似乎出现了整个问题,因为在动画开始CoreGraphics快照时,UINavigationController的黑色(或实际上没有颜色)正在泄漏。因此,将其设置为白色可以防止这种情况。

身份检查器->用户定义的运行时属性


1
我更喜欢这种方法,让Interface Builder UI尽可能多地填充。
DazChong 2015年

iOS 8.4没有帮助
Maksim Kniazev

3
与Xcode 8.3.3完美配合。为了再次强调,必须将其设置为UINavigationController,而不是在viewController上。
jungledev '17

我在tabcon中有一个navcon,当在其中一个VC上使用“在推送时隐藏底部栏”时,两个栏(顶部和底部)上都有阴影。在navcon上设置白色背景可固定两个阴影。谢谢!
nh32rg

6

这似乎是iOS 7.1中引入的错误。就我而言,这是由直接位于导航栏下方的UIToolbar引起的。暗阴影也出现在半透明的标签栏中。

阴影似乎是由UIToolbar的背景视图引起的。我现在在视图控制器和工具栏中使用此解决方法,该工具栏在过渡期间隐藏工具栏的背景视图:

- (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;
    }
}

这是 [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

我提交了此雷达:http : //openradar.appspot.com/16418845


2
如果您不希望使用半透明的导航栏,则您的解决方案很好。
汤姆2014年

有一种更简单的方法来获取backgroundView[self.toolbar valueForKey:@"_backgroundView"]。请注意,这是一个私有API,但是我认为您不会被Apple所吸引,因为_backgroundView它只是一个通用名称。
消极的

这个答案使我明白了我需要做的事情。就我而言,这就像在界面生成器中取消选中UIToolbar上的半透明选项一样简单。
格雷格W

4

半透明的任何条(TabBar或ToolBar)似乎都会发生这种情况。
因此,解决此问题的一种方法是设置_tabBar.translucent = NO;(在我的情况下)。这样可以防止顶部导航栏下方出现不需要的阴影,同时使导航栏保持半透明。不幸的是,底部的条不再是半透明的。

可以将其重新设置为半透明,但是所有这些操作必须在整个推动动画完成后进行,因此切换此属性非常明显。

但是,如果万一底部的条也必须是半透明的,并且我不希望用户看到更改,则可以通过以下方法解决:

/*  create a simple quick animation of the bottom bar
    just before pushing the new controller */
[UIView animateWithDuration:0.1
                 animations:^{
                     _tabBar.barTintColor = [UIColor colorWithWhite:0.97254901960784 alpha:1.0]; // this is the closest color for my case
                     _tabBar.translucent = NO;
                 } completion:^(BOOL finished) {
                     /* now when the animation that makes the bar not translucent
                        is finished we can push the new controller
                        the controller is instantiated before the animation code */
                     [self.navigationController pushViewController:controller animated:YES];
                 }];

然后在中,viewDidAppear:我简单地将其还原:

[UIView animateWithDuration:0.1
             animations:^{
                     _tabBar.barTintColor = nil;
                     _tabBar.translucent = YES;
                 }];

特别是外观上只有一点变化,但是几乎没有引起注意,而且比在导航栏下放置阴影要好得多。

希望它能帮助其他人保持透明状态,直到Apple解决此问题为止,因为在某些情况下,不希望将其隐藏,这与其他帖子中特别建议的不一样。 UITabBar


通过采用@manmal的解决方案,我能够解决此问题- view.backgroundColor在情节提要中为UITabBarController 定义运行时属性,并将其设置为白色。
jamesk 2015年

4

这在Swift中对我有用

AppDelegateon didFinishLaunchingWithOptions方法中,我将其设置为:

UIApplication.shared.windows.first?.backgroundColor = .white

4

这适用于具有亮色深色主题的iOS 13以及较旧的iOS版本。

将以下代码添加到AppDelegate的application(didFinishLaunchingWithOptions)方法中:

if #available(iOS 13.0, *) {
    window?.backgroundColor = UIColor.systemBackground
} else {
    window?.backgroundColor = UIColor.white
}

我也尝试过这种方法,但是在默认模式下显示视图控制器时遇到问题。然后您将看到窗口的白色背景,而不是黑色的背景。看起来很奇怪。您能提出任何克服这种情况的想法吗
varun v nair

3

这是我的变化形式……它所需的代码比汤姆的答案少得多,并且效率更高。如果您想要一个半透明的导航栏,并且还想解决该阴影问题。

在源ViewController中(嵌入在Navigation Controller中)...

- (void)viewDidAppear:(BOOL)animated
{
     self.navigationController.navigationBar.translucent = YES;
}

 - (void)viewWillDisappear:(BOOL)animated
 {
     self.navigationController.navigationBar.translucent = NO;
 }

结果与Tom所做的相同(在视觉上,对于最终用户),并且更易于实现。希望这可以帮助...


3
self.navigationController!.navigationBar.translucent = false;

这对我有用,将其放入您推送新ViewController的函数中


疯狂,但是在所有答案中,只有将其放入功能中才能推送到下一个VC的想法!
Coltuxumab

3

以下内容也可以使导航栏保持透明:

[UIApplication sharedApplication].keyWindow.backgroundColor = [UIColor whiteColor];


1

虽然它与普通的iOS实现不同,但这是解决此问题的好方法:

- (void)viewWillAppear:(BOOL)animated {
    [UIView animateWithDuration:0.35f animations:^{
        self.tabBarController.tabBar.alpha = 1.0f;
    }];
}

- (void)viewWillDisappear:(BOOL)animated {
    [UIView animateWithDuration:0.35f animations:^{
        self.tabBarController.tabBar.alpha = 0.0f;
    }];
}

您将获得选项卡栏的漂亮的淡入/淡出动画。在根目录中添加代码UIViewController


-1

或者,如果您使用的是界面生成器,则只需从导航控制器中选择“导航栏”,然后取消选中“属性”检查器中“样式”和“栏色调”之间的“半透明”复选框即可摆脱这种怪异的效果-

检验员

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.