Ios 11 - UIButton inside UIBarButtonItem causes auto-detection error

I have a known issue with adding a UIButton to a UIBarButtonItem. I tried to add auto-layout restrictions as suggested by stackoveflow , but I get the error message described below.

UIButton *sortButton = [UIButton buttonWithType:UIButtonTypeCustom]; [sortButton setFrame:CGRectMake(10, 0, 100, 30)]; [sortButton setTitle:@"Sort" forState:UIControlStateNormal]; [[sortButton titleLabel] setFont:[UIFont boldSystemFontOfSize:13]]; [sortButton setBackgroundImage:[UIImage imageNamed:@"backgroun-button.png"] forState:UIControlStateNormal]; [sortButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [sortButton addTarget:self action:@selector(sortCollection:) forControlEvents:UIControlEventTouchUpInside]; [sortButton applyNavBarConstraints:100 height:30]; [self setSortCollection:item]; [self setToolbarItems:[NSArray arrayWithObjects:self.sortCollection, nil]]; 

Auto Detection Limitations:

 - (void)applyNavBarConstraints:(CGFloat)width height:(CGFloat)height { if (width == 0 || height == 0) { return; } NSLayoutConstraint* w = [self.widthAnchor constraintEqualToConstant:width]; NSLayoutConstraint * h = [self.heightAnchor constraintEqualToConstant:height]; [w setActive:YES]; [h setActive:YES]; } 

Stack trace:

 [LayoutConstraints] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) ( "<NSAutoresizingMaskLayoutConstraint:0x608000280af0 h=--& v=--& UIToolbar:0x7f85ca1327e0.width == 768 (active)>", "<NSLayoutConstraint:0x6000002826c0 _UIToolbarContentView:0x7f85ca1307b0.trailing == UIToolbar:0x7f85ca1327e0.trailing (active)>", "<NSLayoutConstraint:0x600000282580 H:|-(0)-[_UIToolbarContentView:0x7f85ca1307b0] (active, names: '|':UIToolbar:0x7f85ca1327e0 )>", "<NSLayoutConstraint:0x600000285410 H:|-(0)-[_UIButtonBarStackView:0x7f85ca135660] (active, names: '|':_UIToolbarContentView:0x7f85ca1307b0 )>", "<NSLayoutConstraint:0x600000285460 _UIButtonBarStackView:0x7f85ca135660.trailing == _UIToolbarContentView:0x7f85ca1307b0.trailing (active)>", "<NSLayoutConstraint:0x600000285500 UIButton:0x7f85ca131b90'Sortieren'.width == 100 (active)>", "<NSLayoutConstraint:0x608000280ff0 'UISV-canvas-connection' UILayoutGuide:0x6000001ba240'UIViewLayoutMarginsGuide'.leading == UIButton:0x7f85ca131b90'Sortieren'.leading (active)>", "<NSLayoutConstraint:0x608000280d70 'UISV-canvas-connection' UILayoutGuide:0x6000001ba240'UIViewLayoutMarginsGuide'.trailing == UIButton:0x7f85ca131b90'Sortieren'.trailing (active)>", "<NSLayoutConstraint:0x600000284f10 'UIView-leftMargin-guide-constraint' H:|-(0)-[UILayoutGuide:0x6000001ba240'UIViewLayoutMarginsGuide'](LTR) (active, names: '|':_UIButtonBarStackView:0x7f85ca135660 )>", "<NSLayoutConstraint:0x600000285190 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x6000001ba240'UIViewLayoutMarginsGuide']-(0)-|(LTR) (active, names: '|':_UIButtonBarStackView:0x7f85ca135660 )>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x600000285500 UIButton:0x7f85ca131b90'Sortieren'.width == 100 (active)> Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful. 
+5
source share
3 answers

The panel button is limited left and right, so the width limit must be violated. You can fix this by adding flexible space to the toolbar. This allows you to limit the width of the button and have flexible space filling the rest.

Obj C:

 UIBarButtonItem *flexItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil]; [self setToolbarItems:[NSArray arrayWithObjects:self.sortCollection, flexItem, nil]]; 

Swift:

 let flexItem = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) toolbar.setItems([barButtonItem, flexItem], animated: false) 
+2
source

I also had a problem with iOS11. I solved this by creating my own view with its own XIB and putting a button in it. Then you can easily set restrictions in InterfaceBuilder in XIB. Then, when you really want to use it in barbuttonitem, the code is very short:

 self.customButtonView = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([CustomButtonView class]) owner:nil options:nil] objectAtIndex:0]; [self.customButtonView.button addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside]; self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:self.customButtonView]; 

Just don't forget the second line, where you really need to assign a button selector (which, of course, is an IBOutlet in the user view).

+1
source

Use this simple way to create a button with an automatic layout. The Create button will have a flexible width according to the size of the UIView. No need to add additional restrictions.

 UIButton *sortButton = [UIButton buttonWithType:UIButtonTypeCustom]; [sortButton setFrame:CGRectMake(10, 0, self.view.frame.size.width - 10, 30)]; 
+1
source

Source: https://habr.com/ru/post/1273619/


All Articles