UIBarButtonItem 通过 UIToolBar 在 iOS13 上无法显示

6

我在 iOS13 上通过 UIToolBar 将 UIBarButtonItem 设置为 navigationItem 的 titleView。

构建和运行后,UIBarButtonItem 没有按预期显示。

// 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];

在这段代码中,UIBarButtonItem在iOS12.4.1及以前版本中能够正确显示。在Xcode控制台日志中会显示以下信息。
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.

在苹果开发者论坛上有一个问题描述了同样的现象。

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

根据这个问题,这是一个限制性问题,但其中有关于私有API的内容,并且写明进一步的调查和解决都不可能。

这篇文章指出您使用了UIStackView而没有使用UIToolBar。

我已经向苹果报告了这个问题,但目前还没有得到回复,在iOS13(iOS13.1 beta)新版本中也没有解决此问题。

在iOS13中,UIBarButtonItem通过UIToolBar是否不可用?

我应该像苹果开发者论坛上的文章所描述的那样使用UIStackView而不是UIToolBar吗?


补充。在这段代码中,当代码被执行时,UIBarButtonItem会被显示出来。然而,当另一个屏幕被显示并且原始屏幕被重新绘制或UIAlertController被显示时,UIBarButtonItem会消失。 - BB-8
我也遇到了完全相同的问题。有点奇怪!当我把UIBarButtonItems放在其中时,没有看到可见的UIToolBar。iOS 13.1 beta和Xcode 11 beta 7。 - Arthur Garza
你们找到解决方案了吗? - Kunal Shah
作为临时措施,我们决定不使用viewDidLoad进行处理,而是使用viewWillAppear。此外,已更改为每次显示UIAlertView或屏幕绘制更改时执行按钮编辑和显示处理。我们已向Apple提交了错误反馈,但目前还没有根本解决方案。 - BB-8
2个回答

6

从iOS 13开始,你需要给工具栏设置一个框架。虽然问题是针对Objective-C的,但我用Swift回答。

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

另一种解决方法是将工具栏放在一个stackview中。

在上述Objective-C代码中,当初始化UIToolBar时,Frame大小是由initWithFrame定义的。此外,作为测试,我添加了重新定义toolbar.frame的代码,立即在initWithFrame初始化之后,但结果是相同的。UIBarButtonItem无法放置在UIStackView中,因此不幸的是无法满足此要求。https://forums.developer.apple.com/message/379749#379749 - BB-8
@BB-8,是的,你说得对,我错过了你代码中设置框架的部分。我不知道你不能将UIToolbars添加到UIStackViews中。我也遇到了这个问题,但通过设置框架,我成功解决了它。很抱歉我没能提供更多帮助。 - Christopher Larsen

0

这将防止子视图重新调整大小。

toolbar.autoresizesSubviews = false;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接