3

I am adding NSContraints to a Toolbar of of UINavigationController and I get this error:

Cannot modify constraints for UIToolbar managed by a UINavigationController

In ViewDidLoad:
  self.navigationController.toolbarHidden = NO;
[self.navigationController.toolbar addSubview:_labelName];
[self.navigationController.toolbar addSubview:_labelAddress];

Then I call the method below:

NSLayoutConstraint *nameRight = [NSLayoutConstraint constraintWithItem:_labelName attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.navigationController.toolbar attribute:NSLayoutAttributeRight multiplier:1 constant:20];
NSLayoutConstraint *nameLeft = [NSLayoutConstraint constraintWithItem:_labelName attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.navigationController.toolbar attribute:NSLayoutAttributeLeft multiplier:1 constant:20];
NSLayoutConstraint *nameTop = [NSLayoutConstraint constraintWithItem:_labelName attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.navigationController.toolbar attribute:NSLayoutAttributeTop multiplier:1 constant:0];
NSLayoutConstraint *nameHeight = [NSLayoutConstraint constraintWithItem:_labelName attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.navigationController.toolbar attribute:NSLayoutAttributeHeight multiplier:.5 constant:0];

NSLayoutConstraint *addressRight = [NSLayoutConstraint constraintWithItem:_labelAddress attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.navigationController.toolbar attribute:NSLayoutAttributeRight multiplier:1 constant:20];
NSLayoutConstraint *addressLeft = [NSLayoutConstraint constraintWithItem:_labelAddress attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.navigationController.toolbar attribute:NSLayoutAttributeLeft multiplier:1 constant:20];
NSLayoutConstraint *addressTop = [NSLayoutConstraint constraintWithItem:_labelAddress attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_labelName attribute:NSLayoutAttributeBottom multiplier:1 constant:0];
NSLayoutConstraint *addressHeight = [NSLayoutConstraint constraintWithItem:_labelAddress attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.navigationController.toolbar attribute:NSLayoutAttributeHeight multiplier:.5 constant:0];


[self.navigationController.toolbar addConstraints:@[nameRight, nameLeft, nameTop, nameHeight, addressRight, addressLeft, addressTop, addressHeight]];

Should I create a UIView inside the toolbar of the navigation controller? and put the contraints inside it?

Anbu.Karthik
  • 77,564
  • 21
  • 153
  • 132
Mike Zriel
  • 1,141
  • 1
  • 12
  • 26

2 Answers2

3

Autolayout constraints only work with UIViews and their subclasses. Your alternative is to roll your own toolbar with widgets based only on UIViews.

Link : iOS Autolayout and UIToolbar/UIBarButtonItems

I hope this will resolve your issue.

Community
  • 1
  • 1
IamAnil
  • 496
  • 5
  • 19
0

The issue was you need to add the toolbar items to [self using setToolBarItem] not [self.navigationController.toolbar ..] even though techinically it is the same object.

It is like self.title, sets the navigation controller title, [self setToolbarItems set the toolbar items of the navigation controller toolbar

[self setToolbarItems:@[barButtonItem] animated:NO];  <-- Answer

[self.navigationController.toolbar setItems:@[barButtonItem]]; <-- BAD

For the NSLayout you do that inside a view in the BarButtonItem:

_toolBarView = [[UIView alloc] init];
[_toolBarView addSubview:_labelName];
[_toolBarView addSubview:_labelAddress];

barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:_toolBarView];

NSLayout code:

NSLayoutConstraint *nameRight = [NSLayoutConstraint constraintWithItem:_labelName attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:_toolBarView attribute:NSLayoutAttributeRight multiplier:1 constant:0];
NSLayoutConstraint *nameLeft = [NSLayoutConstraint constraintWithItem:_labelName attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:_toolBarView attribute:NSLayoutAttributeLeft multiplier:1 constant:0];
NSLayoutConstraint *nameTop = [NSLayoutConstraint constraintWithItem:_labelName attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_toolBarView attribute:NSLayoutAttributeTop multiplier:1 constant:0];
NSLayoutConstraint *nameHeight = [NSLayoutConstraint constraintWithItem:_labelName attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:_toolBarView attribute:NSLayoutAttributeHeight multiplier:0.5 constant:0];

NSLayoutConstraint *addressRight = [NSLayoutConstraint constraintWithItem:_labelAddress attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:_toolBarView attribute:NSLayoutAttributeRight multiplier:1 constant:0];
NSLayoutConstraint *addressLeft = [NSLayoutConstraint constraintWithItem:_labelAddress attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:_toolBarView attribute:NSLayoutAttributeLeft multiplier:1 constant:0];
NSLayoutConstraint *addressTop = [NSLayoutConstraint constraintWithItem:_labelAddress attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_labelName attribute:NSLayoutAttributeBottom multiplier:1 constant:0];
NSLayoutConstraint *addressHeight = [NSLayoutConstraint constraintWithItem:_labelAddress attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:_toolBarView attribute:NSLayoutAttributeHeight multiplier:0.5 constant:0];

[_toolBarView addConstraints:@[nameRight, nameLeft, nameTop, nameHeight, addressRight, addressLeft, addressTop, addressHeight]];

Hope this helps!

Mike Zriel
  • 1,141
  • 1
  • 12
  • 26