I\'m trying to build a titleView with constraints that looks like this:
I know how I would do
an0's answer is correct. However, it doesn't help you getting the desired effect.
Here's my recipe for building title views that automatically have the right size:
UIView
subclass, for instance CustomTitleView
that will be later used as the navigationItem
's titleView
.CustomTitleView
. If you want to have your CustomTitleView
being always centered, you'll need to add an explicit CenterX constraint (see code and link below).updateCustomTitleView
(see below) every time your titleView content updates. We need to set the titleView to nil and set it afterwards to our view again to prevent the title view being offset centered. This would happen when the title view changes from wide to narrow.translatesAutoresizingMaskIntoConstraints
Gist: https://gist.github.com/bhr/78758bd0bd4549f1cd1c
Updating CustomTitleView
from your ViewController:
- (void)updateCustomTitleView
{
//we need to set the title view to nil and get always the right frame
self.navigationItem.titleView = nil;
//update properties of your custom title view, e.g. titleLabel
self.navTitleView.titleLabel.text = <#my_property#>;
CGSize size = [self.navTitleView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
self.navTitleView.frame = CGRectMake(0.f, 0.f, size.width, size.height);
self.navigationItem.titleView = self.customTitleView;
}
Sample CustomTitleView.h
with one label and two buttons
#import
@interface BHRCustomTitleView : UIView
@property (nonatomic, strong, readonly) UILabel *titleLabel;
@property (nonatomic, strong, readonly) UIButton *previousButton;
@property (nonatomic, strong, readonly) UIButton *nextButton;
@end
Sample CustomTitleView.m
:
#import "BHRCustomTitleView.h"
@interface BHRCustomTitleView ()
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UIButton *previousButton;
@property (nonatomic, strong) UIButton *nextButton;
@property (nonatomic, copy) NSArray *constraints;
@end
@implementation BHRCustomTitleView
- (void)updateConstraints
{
if (self.constraints) {
[self removeConstraints:self.constraints];
}
NSDictionary *viewsDict = @{ @"title": self.titleLabel,
@"previous": self.previousButton,
@"next": self.nextButton };
NSMutableArray *constraints = [NSMutableArray array];
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(>=0)-[previous]-2-[title]-2-[next]-(>=0)-|"
options:NSLayoutFormatAlignAllBaseline
metrics:nil
views:viewsDict]];
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[previous]|"
options:0
metrics:nil
views:viewsDict]];
[constraints addObject:[NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.titleLabel
attribute:NSLayoutAttributeCenterX
multiplier:1.f
constant:0.f]];
self.constraints = constraints;
[self addConstraints:self.constraints];
[super updateConstraints];
}
- (UILabel *)titleLabel
{
if (!_titleLabel)
{
_titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
_titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
_titleLabel.font = [UIFont boldSystemFontOfSize:_titleLabel.font.pointSize];
[self addSubview:_titleLabel];
}
return _titleLabel;
}
- (UIButton *)previousButton
{
if (!_previousButton)
{
_previousButton = [UIButton buttonWithType:UIButtonTypeSystem];
_previousButton.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_previousButton];
_previousButton.titleLabel.font = [UIFont systemFontOfSize:23.f];
[_previousButton setTitle:@"❮"
forState:UIControlStateNormal];
}
return _previousButton;
}
- (UIButton *)nextButton
{
if (!_nextButton)
{
_nextButton = [UIButton buttonWithType:UIButtonTypeSystem];
_nextButton.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_nextButton];
_nextButton.titleLabel.font = [UIFont systemFontOfSize:23.f];
[_nextButton setTitle:@"❯"
forState:UIControlStateNormal];
}
return _nextButton;
}
+ (BOOL)requiresConstraintBasedLayout
{
return YES;
}
@end