9

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

Monte
  • 1,018
  • 8
  • 15
  • Looking at the animation in the screenshot I'd say the home screen uses a custom `UINavigationBar` (the one from `UINavigationController` is hidden) and when a new screen is pushed the default navigation bar will be shown using `UINavigationController.setNavigationBarHidden(_:animated:)`. – fluidsonic Sep 30 '14 at 23:35

4 Answers4

4

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;
    }
    
Azules
  • 61
  • 1
  • 11
3

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.

2

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).

ttarik
  • 3,824
  • 1
  • 32
  • 51
  • Yeah, i know that twitter use a blurred cover photo. What i just want to understand is how they made these navigation bar. Or whatever these are. The idea that they not even use a navigationbar is good, but i think that the simplest way to reach this is to use custom-transition between different navigation-controller. tnx anyway! – Monte Sep 30 '14 at 23:51
  • if you look at the screenshot you can see that the behind view-controller has a transparency dark level that in CUSTOM push on iOS doesn't exists – Monte Sep 30 '14 at 23:53
  • I don't think it has anything to do with transitions. It's just a regular transition that hides the navigation bar when the user profile view is pushed. The "navigation bar" is just the custom view that shows the cover photo in its normal and blurred forms. – ttarik Sep 30 '14 at 23:56
  • But if you set the navigation bar to be hidden in the profile view (where there is a "custom nav bar with blurred cover"), the bar DISAPPEAR (fading) during transition to the new controller. In twitter it's moved away with the view-controller that will be hidden. This is what i want to reach. – Monte Oct 01 '14 at 00:00
  • 2
    @Monte if you call `setNavigationBarHidden(false, animated: true)` inside `viewWillAppear` of the pushed view controller it should be pushed along with the navigation transition and not fade. – fluidsonic Oct 01 '14 at 00:09
  • @fluidsonic comment should be the answer. – slider Jan 01 '18 at 08:51
0

Try look up this GitHub repo, I think it could help you achieve that effect https://github.com/kingiol/KDInteractiveNavigationController

Dan
  • 810
  • 2
  • 11
  • 29