Objective c 升级到Xcode 5.1和iOS 7.1后,在segue过渡期间导航栏上出现暗影
当我在主-细节导航控制器中的父控制器和子控制器之间来回导航时,我看到顶部导航栏右侧有一个黑影。它是在我升级到Xcode 5.1之后开始的。这感觉很粗糙,让人分心。我怎样才能摆脱它Objective c 升级到Xcode 5.1和iOS 7.1后,在segue过渡期间导航栏上出现暗影,objective-c,uinavigationcontroller,uinavigationbar,segue,Objective C,Uinavigationcontroller,Uinavigationbar,Segue,当我在主-细节导航控制器中的父控制器和子控制器之间来回导航时,我看到顶部导航栏右侧有一个黑影。它是在我升级到Xcode 5.1之后开始的。这感觉很粗糙,让人分心。我怎样才能摆脱它 self.navigationController.navigationBar.translucent = NO; 对于较新的Swift版本: navigationController?.navigationBar.isTranslucent = false 这似乎是iOS 7.1中引入的一个bug。在我的例子中
self.navigationController.navigationBar.translucent = NO;
对于较新的Swift版本:
navigationController?.navigationBar.isTranslucent = false
这似乎是iOS 7.1中引入的一个bug。在我的例子中,它是由位于导航栏正下方的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 findviewer:
@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
我归档了这个雷达:这是我的变体……它需要的代码比tom的答案少得多,而且效率更高。这是如果您想要一个半透明的导航栏,并且还想要修复阴影问题 在源ViewController(嵌入导航控制器中)中 及
结果与Tom所做的相同(对最终用户而言是可视化的),并且更易于实现。希望这能有所帮助……虽然它与股票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
中添加代码
self.navigationController.view.backgroundColor = [UIColor whiteColor];
我通过设置导航控制器视图的背景色解决了这个问题。任何半透明的栏(选项卡栏或工具栏)都会出现这种情况。
因此,解决此问题的一种方法是设置
\u 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];
}];
然后在视图中显示:
我只需将其还原为:
[UIView animateWithDuration:0.1
animations:^{
_tabBar.barTintColor = nil;
_tabBar.translucent = YES;
}];
在外观上有一些特别的变化,但几乎不明显,这比在导航栏下有阴影要好得多
希望它能帮助其他人保持条形图的半透明性,直到苹果修复这种行为,因为条形图在某些情况下是隐藏的,不像其他帖子中建议的那样,特别是对于uitabar
或者如果您使用的是interface builder,您只需从导航控制器中选择导航栏,并在属性检查器中取消选中“样式”和“栏色调”之间的“半透明”复选框,即可消除这种奇怪的效果-
诺梅利夫的答案是完美的。要在Interface Builder中实现同样的效果,并且仍然保持半透明,请选择导航控制器并设置用户定义的运行时属性view.backgroundColor
,如屏幕截图(在Identity Inspector中)所示。对显示此问题的所有导航控制器重复此操作
整个问题的出现似乎是因为在动画开始时CoreGraphics对UINavigationController进行快照时,UINavigationController的黑色(或者实际上没有颜色)正在泄漏。因此,将其设置为白色将防止出现这种情况
这对我来说是可行的。将其放置在推送新ViewController的功能中。以下功能也可以工作,并使导航栏保持透明:
[UIApplication sharedApplication].keyWindow.backgroundColor=[UIColor whiteColor]代码>这在Swift中对我有效
在didfishlaunchwithoptions
方法上的AppDelegate
中,我设置了以下内容:
UIApplication.shared.windows.first?.backgroundColor = .white
这适用于我在iOS 13上使用的亮主题和暗主题,也适用于较旧的iOS版本
将以下代码添加到AppDelegate到应用程序(didFinishLaunchingWithOptions)
方法:
if #available(iOS 13.0, *) {
window?.backgroundColor = UIColor.systemBackground
} else {
window?.backgroundColor = UIColor.white
}
对于那些已经实现了tabBar并希望nav和tabBar都保持半透明的人,在处理了两年痛苦的“推送时tabBar快照”解决方案后,我找到了一个简单的解决方案
诀窍在于:
在选项卡栏上设置clear backgroundView,这会导致视图控制器的布局不同
在第一个按钮下方设置新的模糊效果视图
将模糊视图约束到选项卡栏(UIView)
在我使用tabBar的快照并将tabBar的alpha设置为0之前,这会导致不必要的safeLayoutGuide偏移。由于这个解决方案现在可以访问任何私有变量,我希望这是绿色的,可以转到AppStore(我还没有到那里)
在UITabBarController的viewDidLoad中,我设置了以下内容:
tabBar.backgroundImage = UIImage()
let blurView = UIVisualEffectView()
blurView.effect = UIBlurEffect(style: .systemChromeMaterial)
blurView.frame = tabBar.bounds
blurView.translatesAutoresizingMaskIntoConstraints = false
blurView.isUserInteractionEnabled = false
tabBar.insertSubview(blurView, belowSubview: tabBar.subviews.first!)
let leadingConstraint = blurView.leadingAnchor.constraint(equalTo: tabBar.leadingAnchor, constant: 0)
let trailingConstraint = blurView.trailingAnchor.constraint(equalTo: tabBar.trailingAnchor, constant: 0)
let topConstraint = blurView.topAnchor.constraint(equalTo: tabBar.topAnchor, constant: 0)
let bottomConstraint = blurView.bottomAnchor.constraint(equalTo: tabBar.bottomAnchor, constant: 0)
NSLayoutConstraint.activate([leadingConstraint, trailingConstraint, topConstraint, bottomConstraint])
或:
如果您不需要半透明的导航栏,您的解决方案就可以了。有一种更简单的方法可以获取背景视图<代码>[self.toolbar valueForKey:@“\u backgroundView”]
。请注意,这是一个私有API,但我想你不会被苹果抓到,因为\u backgroundView
只是一个通用名称。这个答案告诉我我需要做什么。在我的例子中,这就像在interface builder中取消选中UIToolbar上的半透明选项一样简单。您将其放置在何处?在主视图控制器的ViewDidLoad方法中,在ViewDidAppari中添加,我认为这实际上是正确的答案。navigationController.view.backgroundColor=.white
在iOS 11上不再工作。@Annjawn,navigationController.view.backgroundColor=.white
在iOS 12上工作。从导航栏中删除半透明不能用于n的情况
UIApplication.shared.windows.first?.backgroundColor = .white
if #available(iOS 13.0, *) {
window?.backgroundColor = UIColor.systemBackground
} else {
window?.backgroundColor = UIColor.white
}
tabBar.backgroundImage = UIImage()
let blurView = UIVisualEffectView()
blurView.effect = UIBlurEffect(style: .systemChromeMaterial)
blurView.frame = tabBar.bounds
blurView.translatesAutoresizingMaskIntoConstraints = false
blurView.isUserInteractionEnabled = false
tabBar.insertSubview(blurView, belowSubview: tabBar.subviews.first!)
let leadingConstraint = blurView.leadingAnchor.constraint(equalTo: tabBar.leadingAnchor, constant: 0)
let trailingConstraint = blurView.trailingAnchor.constraint(equalTo: tabBar.trailingAnchor, constant: 0)
let topConstraint = blurView.topAnchor.constraint(equalTo: tabBar.topAnchor, constant: 0)
let bottomConstraint = blurView.bottomAnchor.constraint(equalTo: tabBar.bottomAnchor, constant: 0)
NSLayoutConstraint.activate([leadingConstraint, trailingConstraint, topConstraint, bottomConstraint])
//Setting background image to empty image to prevent a bug under top right navigation bar corner
tabBar.backgroundImage = UIImage()
//As that turns of the blur effect I am adding a new view imitating the same
let blurView = UIVisualEffectView()
blurView.effect = UIBlurEffect(style: .systemChromeMaterial)
blurView.frame = tabBar.bounds
blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
blurView.isUserInteractionEnabled = false
tabBar.insertSubview(blurView, belowSubview: tabBar.subviews.first!)