Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Black bar appears under navigation bar

There are several similar questions which got no answers but were describe vaguely. I have reduced the problem into a very thin application, and added detailed screenshots. I would highly appreciate a solution for this!

The only involved code is one line added to viewDidLoad of the root VC. The purpose of this line is to make the navigation controller opaque:

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

A critical information for this question is that 'Title1' has a prompt in its navigation item, while 'Title2' has not prompt.

I have a storyboard with one navigation controller, one root VC called "Title1", with a segue button which takes to a second VC called "Title2"

storyboard


When pressing the button here:

pre press


I'm getting this strange screen:

after press


When pressing back (Title1), it gets worse (i.e.: the original label of Title1 was pushed up and now not being seen anymore!!!):

after back

Anyone please??

like image 876
ishahak Avatar asked Jan 12 '14 11:01

ishahak


3 Answers

Late answer but I stumbled across this problem today and found your question and it doesn't have an accepted answer yet.

I got this error while going from a prompted viewController to a non prompted viewController in storyboard.

I got that black bar just like you.

And to fix:

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

This will remove the prompt instantly before switching viewcontroller.

UPDATE

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()
    }
}
like image 166
Arbitur Avatar answered Nov 11 '22 19:11

Arbitur


It appeared as translucent property of UINavigationBar appeared to be messed up with frame other view controllers.

I would recommend following approach.

Create a base view controller from which other view controllers will inherit as follows,

#import "BaseViewController.h"

@interface BaseViewController ()

@end

@implementation BaseViewController

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

other view controllers will inherit above BaseViewController

// interface

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

@interface ViewController : BaseViewController

@end

// implementation

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

Other view controllers without prompt implementation will work as usual however they also needs to inherit from BaseViewController.

like image 34
ldindu Avatar answered Nov 11 '22 19:11

ldindu


The best way to solve this issue is setting the background of the window during push i.e,

let appdelegate = UIApplication.shared.delegate as! AppDelegate
appdelegate.window?.backgroundColor = UIColor.white
like image 33
puneeth Avatar answered Nov 11 '22 20:11

puneeth