Change width of a UIBarButtonItem in a UINavigationBar
Since iOS 11, just setting frame for
customView and not
UIBarButtonItem won't work (like suggested in accepted answer). It seems like adding Autolayout to
UIBarButtonItem overrides the set frame.This post gave me the idea:
navigationItem.leftBarButtonItem?.customView = yourCustomButtonViewlet desiredWidth = 35.0let desiredHeight = 35.0let widthConstraint = NSLayoutConstraint(item: yourCustomButtonView, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: desiredWidth)let heightConstraint = NSLayoutConstraint(item: yourCustomButtonView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: desiredHeight)yourCustomButtonView.addConstraints([widthConstraint, heightConstraint])
Also note, that it is preferred that you use
UIButton as your
CustomView as you have to rely on it to trigger the action.
One approach you might consider is creating a
UIBarButtonItem by calling
initWithCustomView:. This is not ideal in that you don't get "selected" states out of the box AND you have to composite your bordered background (if want that look) with your button image, but with that you can more directly specify a frame for your toolbar item. If you're using text for your title instead of images you may still need add in a background image as a subview. Anyway, I'm having the same problem right now and this code works for me:
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"button-image.png"]];imageView.frame = CGRectMake(0, 0, 43, 30);UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:imageView];self.navigationItem.leftBarButtonItem = barButtonItem;
Right now this is the only way I know of restricting the auto-sizing of the
UIBarButtonItems added to the
The key thing with this is to realise that you are changing the custom view's width, rather than the
The code is therefore:
CGRect resizedFrame = myBarButtonItem.customView.frame;resizedFrame.size.width = myNewWidth;myBarButtonItem.customView.frame = resizedFrame;
You will also need to trigger the layout change:
All this goes without saying that the layout is being done with Auto Sizing and frames. Incursions into navigation bars with Auto Layout yielded no success. See my question Auto Layout with UINavigationBar and UIBarButtonItem.
Sorry just realised that my code is almost identical to @oscartzombie. Not intentional! I'll leave this answer as I think it's worth adding the layout and other points, in addition to explaining without reference to Interface Bulder or images specifically.