2
votes

I have a couple of upcoming designs to implement. These designs have some overlap that I want to make general for my project. The app should be navigation based and all have company brand image in the navbar, but the navbar should be larger than it originally is, with the title below the main image.

Custom UINavigationBar with company brand

The top blue part is the same brand image throughout the project, the below gray part is where the title label resides, which means that the title label should be adjusted. I want to be able to use setTitle for my view controllers. The back button should be centered in the blue part, so slightly adjusted towards the top of the screen, instead of centered in the navigation bar.

I've gotten some inspiration from the following questions and a category would be a nice way to go or am I in the wrong here? Do you have any suggestions?

Objective-C: Background image and title in Navigation Bar

UINavigationBar custom title position

Changing the UINavigationBar background image

4

4 Answers

2
votes

You can do like this in the viewDidLoad method

UIView *navbar = self.navigationBar;
navbar.translatesAutoresizingMaskIntoConstraints = NO;
[navbar addConstraints:[NSLayoutConstraint
                        constraintsWithVisualFormat:@"V:[navbar(80)]" // custom height
                        options:0
                        metrics:nil
                        views:NSDictionaryOfVariableBindings(navbar)]];

[navbar addConstraints:[NSLayoutConstraint
                        constraintsWithVisualFormat:@"[navbar(320)]"
                        options:0
                        metrics:nil
                        views:NSDictionaryOfVariableBindings(navbar)]];

self.widthConstraint = navbar.constraints[1]; // width is the 2nd constraint

For adjusting back button use custom back button image and position an icon within image as you wish. Use [UINavigationBar appearance] to set custom back button.

[[UINavigationBar appearance] setBackIndicatorImage:[UIImage imageNamed:@"IconBack"]];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage new]];

For adjusting titles use corresponding methods of UINavigationBar and UIBarButtonItem appearances.

[[UINavigationBar appearance] setTitleVerticalPositionAdjustment:10 forBarMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -10) forBarMetrics:UIBarMetricsDefault];
1
votes

As per this link : https://stackoverflow.com/a/7688626/667586

Create a UINavigationBar Category with a custom sizeThatFits.

@implementation UINavigationBar (customNav)
- (CGSize)sizeThatFits:(CGSize)size {
CGSize newSize = CGSizeMake(self.frame.size.width,70);
return newSize;
}
@end

For Title, use

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index;  // tell table which section corresponds to section title/index (e.g. "B",1))
1
votes

On a project I did something like this:

self.navigationItem.titleView = [MyClass getTitleView:parameter];
self.navigationController.navigationBar.frame = CGRectMake(0.0, 0.0, 320.0, self.navigationItem.titleView.frame.size.height);

UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
.
.
.

// 44 is the default height of a nav bar
if (self.navigationItem.titleView.frame.size.height > 44) {
    [backButton setImageEdgeInsets:UIEdgeInsetsMake(-self.navigationItem.titleView.frame.size.height/4, 0, self.navigationItem.titleView.frame.size.height/4, 0)];
}
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];

The method [MyClass getTitleView:parameter] gives you the view you want with the labels and images you need, then you readjust the navigation bar and buttons, the hardcoded constants on the button insets are just to center the button vertically because our nav bar also had an extra label at the bottom, also you might want to fix the width of the bar, ours supports portrait only.

We have this code on the viewWillAppear: method because only one class uses it but a category sounds reasonable if you don't have a base ViewController to subclass from.

0
votes

Not sure if it works in all cases, but here is a starting point.

I noticed that UINavigationBar height could be changed via autolayout constraints. By default bar's autoresizing mask is translated into constraints. I turned it off and added width and height constraints manually. Width constraint depends on orientation and should be changed when orientation transition occurs. All changes are performed in UINavigationController subclass.

@interface NavigationController ()
@property (strong, nonatomic) NSLayoutConstraint *widthConstraint;
@end

@implementation NavigationController

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIView *navbar = self.navigationBar;
    navbar.translatesAutoresizingMaskIntoConstraints = NO;

    [navbar addConstraints:[NSLayoutConstraint
                            constraintsWithVisualFormat:@"V:[navbar(80)]" // custom height
                            options:0
                            metrics:nil
                            views:NSDictionaryOfVariableBindings(navbar)]];

    [navbar addConstraints:[NSLayoutConstraint
                            constraintsWithVisualFormat:@"[navbar(320)]"
                            options:0
                            metrics:nil
                            views:NSDictionaryOfVariableBindings(navbar)]];

    self.widthConstraint = navbar.constraints[1]; // width is the 2nd constraint
}

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    CGSize size = [UIScreen mainScreen].bounds.size;

    self.widthConstraint.constant =
        UIInterfaceOrientationIsLandscape(toInterfaceOrientation)
            ? size.height
            : size.width;

    [UIView animateWithDuration:duration animations:^{
        [self.navigationBar layoutIfNeeded];
    }];
}

@end

For adjusting back button use custom back button image and position an icon within image as you wish. Use [UINavigationBar appearance] to set custom back button.

[[UINavigationBar appearance] setBackIndicatorImage:[UIImage imageNamed:@"IconBack"]];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage new]];

For adjusting titles use corresponding methods of UINavigationBar and UIBarButtonItem appearances.

[[UINavigationBar appearance] setTitleVerticalPositionAdjustment:10 forBarMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -10) forBarMetrics:UIBarMetricsDefault];