9

How can I remove the gloss/shine effect from the buttons on navigation bars? If I customize the navigation bar by using a custom image the buttons are not affected, can I remove the effect from them (the line and glossing), or define a hex color code for the whole button, or even a custom image for them too?

Justin Gallagher
  • 3,242
  • 21
  • 25
Peter V
  • 2,478
  • 6
  • 36
  • 54
  • 1
    @Rudy - If you believe the question to be a duplicate of another, please vote to close it as such rather than editing the body of the question. – Brad Larson Sep 05 '11 at 18:38
  • This is a possible duplicate of [iOS: How to replace Search Bar background shine/glow with one color](http://stackoverflow.com/questions/6696200/ios-how-to-replace-search-bar-background-shine-glow-with-one-color) – Rudy Velthuis Sep 05 '11 at 19:13

3 Answers3

18

I just went through the process of figuring this out. Basically, you need to create custom stretchable images and use them as the button's background to get rid of the shine. Replacing the back buttons in a UINavigationController is a bit tougher. For that I used a UINavigationControllerDelegate to replace the default back button with my custom button.

Here's some code:

  1. Create a category on UIBarButtonItem that creates your custom button. Here's mine. I use this category to customize both regular bar buttons and back buttons:

    @interface UIBarButtonItem (UIBarButtonItem_customBackground)
    
    + (id) customBarButtonWithTitle:(NSString *)title target:(id)target selector:(SEL)selector;
    + (id) customBackButtonWithTitle:(NSString *)title target:(id)target selector:(SEL)selector;
    
    @end
    
    @implementation UIBarButtonItem (UIBarButtonItem_customBackground)
    
    + (id) customButtonWithImageNamed:(NSString *)imageName selectedImageNamed:(NSString *)selectedImageName leftCapWidth:(CGFloat)leftCapWidth edgeInsets:(UIEdgeInsets)edgeInsets title:(NSString *)title target:(id)target selector:(SEL)selector {
        UIButton* customButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [customButton addTarget:target action:selector forControlEvents:UIControlEventTouchUpInside];
        customButton.titleLabel.font = [UIFont boldSystemFontOfSize:12.0f];
        customButton.titleLabel.shadowColor = [UIColor colorWithRed:0.0f/255.0f green:0.0f/255.0f blue:0.0f/255.0f alpha:0.25f];
        customButton.titleLabel.shadowOffset = CGSizeMake(0.0f, -1.0f);
        customButton.titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
        customButton.titleEdgeInsets = edgeInsets;
        UIImage* navButtonBackgroundImage = [[UIImage imageNamed:imageName] stretchableImageWithLeftCapWidth:leftCapWidth topCapHeight:0.0f];
        UIImage* navButtonPressedBackgroundImage = [[UIImage imageNamed:selectedImageName] stretchableImageWithLeftCapWidth:leftCapWidth topCapHeight:0.0f];
        [customButton setBackgroundImage:navButtonBackgroundImage forState:UIControlStateNormal];
        [customButton setTitle:title forState:UIControlStateNormal];
        [customButton setBackgroundImage:navButtonPressedBackgroundImage forState:UIControlStateHighlighted];
        [customButton setBackgroundImage:navButtonPressedBackgroundImage forState:UIControlStateSelected];
    
        CGSize size = CGSizeMake(30.0f, 30.0f);
        if (title != nil) {
            size = [[NSString stringWithString:title] sizeWithFont:customButton.titleLabel.font];
        }
        customButton.frame = CGRectMake(0.0f, 0.0f, size.width + 20.0f, 30.0f);
        customButton.layer.shouldRasterize = YES;
        customButton.layer.rasterizationScale = [[UIScreen mainScreen] scale];
        return [[[UIBarButtonItem alloc] initWithCustomView:customButton] autorelease];
    }
    
    + (id) customBarButtonWithTitle:(NSString *)title target:(id)target selector:(SEL)selector {
        return [self customButtonWithImageNamed:@"navButtonBG.png" 
                     selectedImageNamed:@"navButtonPressedBG.png" 
                           leftCapWidth:6.0f 
                             edgeInsets:UIEdgeInsetsMake(0.0f, 5.0f, 0.0f, 5.0f) 
                                  title:title 
                                 target:target 
                               selector:selector];
    }
    
    + (id) customBackButtonWithTitle:(NSString *)title target:(id)target selector:(SEL)selector {    
        return [self customButtonWithImageNamed:@"backButtonBG.png" 
                     selectedImageNamed:@"backButtonPressedBG.png" 
                           leftCapWidth:12.0f 
                             edgeInsets:UIEdgeInsetsMake(0.0f, 11.0f, 0.0f, 5.0f) 
                                  title:title 
                                 target:target 
                               selector:selector];
    }
    
    @end
    
  2. Add the button to your UINavigationBar

    UIBarButtonItem* logoutButton = [UIBarButtonItem customBarButtonWithTitle:@"Logout" target:self selector:@selector(logout)];
    self.navigationItem.rightBarButtonItem = logoutButton;
    
  3. If you also want to replace the UINavigationController's back buttons, setup a UINavigationControllerDelegate and implement the willShowViewController method like so:

    - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
        if([navigationController.viewControllers count ] > 1) {
            UIViewController* backViewController = [navigationController.viewControllers objectAtIndex:(navigationController.viewControllers.count - 2)];
            NSString* backText = backViewController.title;
            UIBarButtonItem* newBackButton = [UIBarButtonItem customBackButtonWithTitle:backText target:navigationController selector:@selector(popViewControllerAnimated:)];
            viewController.navigationItem.leftBarButtonItem = newBackButton;
            viewController.navigationItem.hidesBackButton = YES;
        }
    }
    
  4. Here are the stretchable images I'm using:

    • Back button: back button Pressed: enter image description here
    • Regular button: enter image description here Pressed: enter image description here
Justin Gallagher
  • 3,242
  • 21
  • 25
  • Thanks so much for the code, Justin. I found that just dropping in your sample images didn't quite work out of the box (maybe because they aren't retina assets?). Here are some examples that I found worked better for me: http://cl.ly/image/441k1H1R1J1e (normal BBI) and http://cl.ly/image/0K0O3b101P3R (back BBI). – Tim Arnold Jan 21 '13 at 23:59
2

For changing the back button it is not necessary to implement the delegate method uinavigationcontroller.

You only need set the hidesBAckButton property to YES after setting the desired backbutton as @Justin Gallacher explained perfectly.

self.navigationItem.leftBarButtonItem = [UIBarButtonItem customBackButtonWithTitle:@"Back" target:self.navigationController   selector:@selector(popViewControllerAnimated:)];
self.navigationItem.hidesBackButton = YES;
Ilker Baltaci
  • 11,644
  • 6
  • 63
  • 79
  • This isn't even necessary, setting the leftBarButtonItem property will override the back button – Daniel Jan 29 '13 at 19:46
0

you have to use the custom button with images without any gloss effect on the images by which you can get rid of the gloos effect of the button from navbar.

B25Dec
  • 2,301
  • 5
  • 31
  • 54