【问题标题】:Black bar appears under navigation bar导航栏下方出现黑条
【发布时间】:2014-01-31 04:05:19
【问题描述】:

有几个类似的问题没有得到答案,但描述模糊。我已将问题简化为一个非常薄的应用程序,并添加了详细的屏幕截图。我非常感谢您的解决方案!

唯一涉及的代码是添加到根 VC 的 viewDidLoad 中的一行代码。此行的目的是使导航控制器不透明:

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.navigationController.navigationBar.translucent = NO;
}

此问题的一个关键信息是“Title1”在其导航项中有提示而“Title2”没有提示

我有一个带有一个导航控制器的情节提要,一个名为“Title1”的根 VC,以及一个转到第二个名为“Title2”的 VC 的 segue 按钮


在此处按下按钮时:


我遇到了这个奇怪的屏幕:


当按回(Title1)时,情况变得更糟(即:Title1的原始标签被推上去,现在再也看不到了!!!):

有人请吗??

【问题讨论】:

  • 这里的 Prompt1 是什么?
  • 是导航项的提示
  • 是导航项的标题吗?
  • 我也遇到过这个问题!我是先写一个iOS 7的程序,然后在iOS 6上测试,然后黑条出现在6。我的解决办法就是把view的frame设置在CGPoint(0,0)
  • 让我也... :)

标签: ios ios7 navigationitem


【解决方案1】:

迟到的答案,但我今天偶然发现了这个问题,发现了你的问题,但它还没有被接受的答案。

我在故事板中从提示的 viewController 转到未提示的 viewController 时遇到此错误。

我和你一样有那个黑条。

并修复:

// In prompted vc
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    UIView.setAnimationsEnabled(false)
    self.navigationItem.prompt = nil
    UIView.setAnimationsEnabled(true)
}

这将在切换视图控制器之前立即删除提示。

更新

func prompt() -> String? {
    return nil
}

override func viewWillAppear(animated: Bool) {
    let action = { self.navigationItem.prompt = self.prompt() }
    
    if self.navigationController?.viewControllers.count <= 1 {
        UIView.performWithoutAnimation(action)
    }
    else {
        action()
    }
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {        
    UIView.performWithoutAnimation {
        self.navigationItem.prompt = (segue.destinationViewController as? ViewController)?.prompt()
    }
}

【讨论】:

  • 这仅在您转到另一个视图时才有效。在导航栏和后退按钮的情况下,不执行 segue。尝试将该代码放在 viewWillDisappear 中,但没有成功
  • @lostintranslation 那是因为你需要把它放到你支持的 VC 中的 viewWillAppear 中。我会更新我的答案
【解决方案2】:

它显示为 UINavigationBar 的半透明属性似乎与其他视图控制器的框架混淆了。

我会推荐以下方法。

创建一个基本视图控制器,其他视图控制器将从该控制器继承,如下所示,

#import "BaseViewController.h"

@interface BaseViewController ()

@end

@implementation BaseViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.navigationController.navigationBar.translucent = NO;
}

其他视图控制器将继承BaseViewController之上

// 接口

#import <UIKit/UIKit.h>
#import "BaseViewController.h"

@interface ViewController : BaseViewController

@end

// 实现

#import "ViewController.h"

@implementation ViewController

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    // Here translucent property is enabled when the view is about to be disappeared.
    // However note that, translucent property needs to be enabled only on those view controllers which has prompt set on their navigation items.
    self.navigationController.navigationBar.translucent = YES;
}

其他没有及时实现的视图控制器将照常工作,但它们也需要从 BaseViewController 继承。

【讨论】:

  • 谢谢@Idindu。我需要检查你的方法,但不确定我是否在关注你。对于我的应用,即使没有提示,半透明也必须设置为 NO,因为我需要内容出现在导航栏下方
  • 是的,我只是将其设置为 NO,对于已设置提示的视图控制器,当视图控制器即将消失但由于它在 BaseViewController 中再次设置,您其他视图控制器将继承自。
  • 设置 navigationController.navigationBar.isTranslucent = true 是对我有用的修复
【解决方案3】:

解决此问题的最佳方法是在推送期间设置窗口的背景,即

let appdelegate = UIApplication.shared.delegate as! AppDelegate
appdelegate.window?.backgroundColor = UIColor.white

【讨论】:

  • 最简单的修复方法。 :) 谢谢
【解决方案4】:

似乎 Xcode 在更改导航栏高度时存在一些问题,因为主控制器视图没有相应地调整大小。

我找到了一个解决方案,但不确定它是否是最好的......但它正在工作。

只需在您的第一个视图控制器(带有提示的视图控制器)中继承您的 viewWillAppearviewWillDisappear 方法:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    self.navigationItem.prompt = @"Prompt1";

    [UIView animateWithDuration:UINavigationControllerHideShowBarDuration
                          delay:0.0
                        options: UIViewAnimationOptionCurveEaseOut
                     animations:^{
                         [self.view setFrame:CGRectMake(0, 94, 320, 386)];
                     }
                     completion:^(BOOL finished){
                     }];

}

- (void) viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    // Sets prompt to nil
    self.navigationItem.prompt = nil;

    [UIView animateWithDuration:UINavigationControllerHideShowBarDuration
                          delay:0.0
                        options: UIViewAnimationOptionCurveEaseOut
                     animations:^{
                         [self.view setFrame:CGRectMake(0, 64, 320, 416)];
                     }
                     completion:^(BOOL finished){
                     }];
}

我没有关注框架尺寸(它适用于 3.5 英寸 iPhone 框架尺寸)。您必须计算此尺寸,否则您可能会在使用较大的屏幕时遇到一些问题。

【讨论】:

  • 嗨@Damien,非常感谢您的解决方案。真正的应用程序有很多屏幕,所以它肯定不是一个很好的解决方案,所以我会等着看有没有更好的解决方案
【解决方案5】:

这个帖子上的最佳答案刚刚为我解决了这个问题,谢谢。

事情是这样的,我正在开发的应用程序使用协调器和自动布局,所以看到这表明动画需要关闭。我不得不将导航控制器的推送视图控制器函数的动画参数更改为 false。

例如:

navigationController?.pushViewController(view, animated: false)

【讨论】: