Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Navigation Bar with different colors in every view-controller like Twitter (not with setbartintcolor)

AS you can see in the image below, Twitter use different navigation bar color for each view-controller that is pushed.

I've tried almost everything (setbackgroundimage, backgroundcolor, bartintcolor, etc) but nothing seems to work. What i think is that Twitter use custom transition to SIMULATE the push, because, what it seems to me is that every view-controller is presented has his own navigation bar with his own color.

enter image description hereenter image description here

like image 533
Monte Avatar asked Sep 30 '14 23:09

Monte


3 Answers

If you want to handle navigationBar with different barTintColors, Code School had a tutorial about it. (iOS App: Creating a Custom Nav Bar) It could also extended to different backgrounds by using setBackgroundImage:forBarMetrics: method.

There are following four steps:

  1. Handle this in viewWillAppear of the source view controller, hide the navigationBar that navigationController provided and create a new navigationBar to the superView.

    - (void)styleNavBar
    {
        // 1. hide the existing nav bar
        [self.navigationController setNavigationBarHidden:YES animated:NO];
    
        // 2. create a new nav bar and style it
        UINavigationBar *newNavBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), 64.0)];
        [newNavBar setTintColor:[UIColor whiteColor]];
    
        // 3. add a new navigation item w/title to the new nav bar
        UINavigationItem *newItem = [[UINavigationItem alloc] init];
        newItem.title = @"Source";
        [newNavBar setItems:@[newItem]];
    
        // 4. add the nav bar to the main view
        [self.view addSubview:newNavBar];
    }
    
  2. Do the same trick in viewWillAppear of the destination view controller, and create a backBarButtonItem as new navigationBar'sleftBarButtonItem.

    - (void)styleNavBar 
    {
        [self.navigationController setNavigationBarHidden:YES animated:NO];
        UINavigationBar *newNavBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), 64.0)];
        [newNavBar setTintColor:[UIColor blueColor]];
        UINavigationItem *newItem = [[UINavigationItem alloc] init];
        newItem.title = @"Destination";
    
        // BackButtonBlack is an image we created and added to the app’s asset catalog
        UIImage *backButtonImage = [UIImage imageNamed:@"BackButtonBlack"];
    
        // any buttons in a navigation bar are UIBarButtonItems, not just regular UIButtons. backTapped: is the method we’ll call when this button is tapped
        UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithImage:backButtonImage
                                                                              style:UIBarButtonItemStylePlain
                                                                             target:self
                                                                             action:@selector(backTapped:)];
    
        // the bar button item is actually set on the navigation item, not the navigation bar itself.
        newItem.leftBarButtonItem = backBarButtonItem;
    
        [newNavBar setItems:@[newItem]];
        [self.view addSubview:newNavBar];
    }
    
  3. Fill out the backTapped: method so that user is able to tap-to-popover from destination view controller.

    - (void)backTapped:(id)sender
    {
        [self.navigationController popViewControllerAnimated:YES];
    }
    
  4. Considering the swipe-to-pop situation, setting the gesture recognizer’s delegate to self in viewWillAppear of the destination view controller. (The author: The solution here is a bit of a hack.)

    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
        [self styleNavBar];
    
        __weak id weakSelf = self;
        self.navigationController.interactivePopGestureRecognizer.delegate = weakSelf;
    }
    
like image 86
Azules Avatar answered Nov 12 '22 07:11

Azules


This for swift3 :

  1. You can set the original navbar background with an empty image:

    self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
    self.navigationController?.navigationBar.shadowImage = UIImage()
    
  2. With this all of the others VC in the view hierarchy will adopt an transparent nav bar.

  3. In the other VC if you want to set an custom image or a custom color simply put a background view in the position of the navbar, this in the view did load method of the particular view controller.

    let viewNavBar = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 64))
    viewNavBar.backgroundColor = UIColor.white
    view.addSubview(viewNavBar)
    

Whit this you can set any background or image inside the viewNavBar and don't mess with the overall configuration of the navigation bar.

like image 35
Giovanny Piñeros Avatar answered Nov 12 '22 07:11

Giovanny Piñeros


Twitter doesn't change the navigation bar colour. When you're looking at a user's profile, it's a blurred version of the user's cover photo.

As you can see in the transition, the whole user profile view replaces the previous view. The navigation bar doesn't change, it is replaced. They might not even use a UINavigationBar (or at least not the one from the navigation controller).

The "bar" is a custom view that shows the user's cover photo, with the back/search/tweet buttons appearing in their usual positions. The user's cover photo shrinks, blurs and attaches to the top of the screen when you have scrolled down - and at this point, it looks like a normal navigation bar. The user's name and tweet count also scrolls up to the center of the navigation bar at this point.

It's quite intriguing, and their whole view structure for a user's profile probably uses a bunch of tricks. But it's not exactly a simple task to imitate their profile view, and they do much more than just change the tint of their navigation bar. If you just want to do this, Undo's answer works well. However, you may also have to reset the tint colour in your viewWillAppear method (of the old and new views).

like image 2
ttarik Avatar answered Nov 12 '22 08:11

ttarik