UIBarButtonItem via UIToolBar is not displayed on iOS13
Asked Answered
B

2

6

I set UIBarButtonItem via UIToolBar to the titleView of navigationItem on iOS13.

After building and running, the UIBarButtonItem was not displayed as expected.

// note
UIBarButtonItem *noteButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemCompose target:self action:@selector(noteViewAction)];

// camera
UIBarButtonItem *cameraButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemCamera target:self action:@selector(cameraViewAction)];

// spacer
UIBarButtonItem *space = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
space.width = 50.0;


// Toolbar
UIToolbar *toolbar;
toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 300.0f, 44.0f)];
toolbar.autoresizingMask = UIViewAutoresizingFlexibleHeight;
toolbar.items = [NSArray arrayWithObjects:space, noteButton, space, cameraButton, nil];
toolbar.backgroundColor = [UIColor clearColor];

[self.navigationItem setTitleView:toolbar];

In this code, UIBarButtonItem is displayed correctly in iOS12.4.1 and earlier versions.

The following message is displayed in the Xcode console log.

2019-08-29 19:22:39.208598+0900 UINavigationItemBugOnIos13[559:49829] [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:0x2839cf980 h=--& v=--& _UIToolbarContentView:0x102c14c20.width == 0   (active)>",
    "<NSLayoutConstraint:0x2839cff20 UIImageView:0x102d2aff0.width <= _UIModernBarButton:0x102d29c40.width   (active)>",
    "<NSLayoutConstraint:0x2839c00f0 UIImageView:0x102d2ca80.width <= _UIModernBarButton:0x102d2b550.width   (active)>",
    "<NSLayoutConstraint:0x2839c9720 H:|-(0)-[_UIButtonBarStackView:0x102c18130]   (active, names: '|':_UIToolbarContentView:0x102c14c20 )>",
    "<NSLayoutConstraint:0x2839c9770 _UIButtonBarStackView:0x102c18130.trailing == _UIToolbarContentView:0x102c14c20.trailing   (active)>",
    "<NSLayoutConstraint:0x2839cd9f0 'IB_Leading_Leading' H:|-(16)-[_UIModernBarButton:0x102d29c40]   (active, names: '|':_UIButtonBarButton:0x102d29a60 )>",
    "<NSLayoutConstraint:0x2839ce490 'IB_Leading_Leading' H:|-(>=10)-[_UIModernBarButton:0x102d2b550]   (active, names: '|':_UIButtonBarButton:0x102d2b370 )>",
    "<NSLayoutConstraint:0x2839cda40 'IB_Trailing_Trailing' H:[_UIModernBarButton:0x102d29c40]-(>=11.5)-|   (active, names: '|':_UIButtonBarButton:0x102d29a60 )>",
    "<NSLayoutConstraint:0x2839ce4e0 'IB_Trailing_Trailing' H:[_UIModernBarButton:0x102d2b550]-(16)-|   (active, names: '|':_UIButtonBarButton:0x102d2b370 )>",
    "<NSLayoutConstraint:0x2839c4140 'UISV-canvas-connection' UILayoutGuide:0x2823ecfc0'UIViewLayoutMarginsGuide'.leading == UIView:0x102c3eb90.leading   (active)>",
    "<NSLayoutConstraint:0x2839c42d0 'UISV-canvas-connection' UILayoutGuide:0x2823ecfc0'UIViewLayoutMarginsGuide'.trailing == UIView:0x102c3ee70.trailing   (active)>",
    "<NSLayoutConstraint:0x2839c4320 'UISV-spacing' H:[UIView:0x102c3eb90]-(0)-[_UIButtonBarButton:0x102d29a60]   (active)>",
    "<NSLayoutConstraint:0x2839c4370 'UISV-spacing' H:[_UIButtonBarButton:0x102d29a60]-(0)-[UIView:0x102c3ed00]   (active)>",
    "<NSLayoutConstraint:0x2839c43c0 'UISV-spacing' H:[UIView:0x102c3ed00]-(0)-[_UIButtonBarButton:0x102d2b370]   (active)>",
    "<NSLayoutConstraint:0x2839cf070 'UISV-spacing' H:[_UIButtonBarButton:0x102d2b370]-(0)-[UIView:0x102c3ee70]   (active)>",
    "<NSLayoutConstraint:0x2839c9590 'UIView-leftMargin-guide-constraint' H:|-(0)-[UILayoutGuide:0x2823ecfc0'UIViewLayoutMarginsGuide'](LTR)   (active, names: '|':_UIButtonBarStackView:0x102c18130 )>",
    "<NSLayoutConstraint:0x2839c9630 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x2823ecfc0'UIViewLayoutMarginsGuide']-(0)-|(LTR)   (active, names: '|':_UIButtonBarStackView:0x102c18130 )>"
)

Will attempt to recover by breaking constraint 
NSLayoutConstraint:0x2839c00f0 UIImageView:0x102d2ca80.width <= _UIModernBarButton:0x102d2b550.width   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.

There is a question on the Apple Developer Forum that describes the same phenomenon.

https://forums.developer.apple.com/thread/121474

According to this, it is a problem of restrictions, but it is a part about private API, and it is written that further investigation and resolution are not possible.

This article states that you used UIStackView without using UIToolBar.

I have already reported a bug to Apple regarding this issue, but there is no response from Apple at this time, and the problem has not been resolved in the new beta version of iOS13(iOS13.1 beta).

In iOS13, did UIBarButtonItem via UIToolBar become unavailable?

Should I use UIStackView instead of UIToolBar as described in the Apple Developer Forum article?

Blemish answered 29/8, 2019 at 13:19 Comment(4)
Supplement.In this code, UIBarButtonItem is displayed when the code is executed. However, UIBarButtonItem disappears when the screen is redrawn when another screen is displayed and the original screen is displayed, or UIAlertController is displayed.Blemish
I'm having this exact same issue. Kinda weird! No visible UIToolBar when I place UIBarButtonItems in it. iOS 13.1 beta and Xcode 11 beta 7Upstart
Did y'all find a solution for this?Mound
As a provisional measure, we decided not to do the processing with viewDidLoad, but with viewWillAppear. In addition, it has been changed so that button editing and display processing are performed each time UIAlertView is displayed or screen drawing changes. We have submitted a bug feedback to Apple, but there is no fundamental resolution at this time.Blemish
B
6

As of iOS 13 you need to give the toolbar a frame. Know the question is objective-c, but replying in swift.

   doneToolbar.frame = CGRect(x: 0,
                              y: 0,
                              width: view.bounds.width,
                              height: 40)

Another solution is to put your toolbar inside of a stackview

Boxwood answered 25/11, 2019 at 17:57 Comment(2)
In the above Objective-c code, when UIToolBar is initialized, Frame size is defined by initWithFrame. Also, As a test, I added code to redefine toolbar.frame immediately after initialization with initWithFrame, but the result was the same. UIBarButtonItem cannot be placed in UIStackView, so unfortunately this requirement is not met. forums.developer.apple.com/message/379749#379749Blemish
@Blemish yeah you're right, I missed the frame being set in your code. Was unaware you couldn't add UIToolbars to UIStackViews. I ran into this issue and was able to solve it by setting the frame, sorry I couldn't be more help.Boxwood
R
0

It'll prevent subviews from resizing.

toolbar.autoresizesSubviews = false;
Refractor answered 11/3, 2020 at 5:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.