自定义 UIToolbar 太靠近 iPhone X 上的主页指示器

Posted

技术标签:

【中文标题】自定义 UIToolbar 太靠近 iPhone X 上的主页指示器【英文标题】:Custom UIToolbar too close to the home indicator on iPhone X 【发布时间】:2018-01-13 02:19:16 【问题描述】:

我有一个自定义UIToolbar,当标签栏隐藏时我会显示它。 iPhone X 上的工具栏按钮离主页指示器太近了:

let toolbar = UIToolbar()
let height = tabBarController?.tabBar.frame.height
toolbar.frame = CGRect(x: 0, y: view.bounds.height - height, width: view.bounds.width, height: height)
toolbar.autoresizingMask = [.flexibleWidth, .flexibleTopMargin]
view.addSubview(toolbar)

按钮太靠近主页指示器

这就是我想要的样子(邮件应用)^

由于这是一个自定义视图,我知道我可以更改 y 位置并将其移动到安全区域的底部,但我宁愿移动按钮。我使用的是普通的UIBarButtonItem,中间有灵活的空间。

【问题讨论】:

已回复here 你是如何解决这个问题的?你能帮忙吗? @Shah 我没有使用UIToolbar,而是创建了自己的带有水平堆栈视图的UIView 知道了。非常感谢 【参考方案1】:

ios 11 中,Apple 弃用了 top and bottom layout guides 并替换为单个 safe area layout guide。 所以使用Safe Area Layout Guides 将视图从主页指示器移到上方。

使用 故事板:

转到StoryboardInterface Builder Document section 勾选Use Safe Area Layout Guides复选框 然后将Bottom Constraint 更改为相对于Safe Area

现在视图在Home Indicator 上方对齐。

或通过编码,

   toolbar.translatesAutoresizingMaskIntoConstraints = false

   NSLayoutConstraint.activate([
        toolbar.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
        toolbar.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
        toolbar.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
        toolbar.heightAnchor.constraint(equalToConstant: 50)
        ])

查看这篇文章Positioning Content Relative to the Safe Area

【讨论】:

当用户单击按钮时,我正在隐藏标签栏并显示工具栏。就像单击“选择”时照片应用程序所做的一样。如果我将工具栏约束到安全区域,它的底部将与隐藏标签栏的顶部对齐(这意味着在工具栏和视图底部之间会有一个标签栏大小的间隙) . 用户想要扩展工具栏的高度,同时在栏的顶部对齐内容。这个答案使整个酒吧远离安全区域。虽然这对其他场景很有帮助,但这显然是用户不想要的结果。【参考方案2】:

您无需设置明确的高度或大小即可使其工作,只需利用UIToolbarDelegate 采用的layoutMarginsGuideUIBarPositioningDelegate 协议即可。 首先,布局工具栏,使其固定在视图 layoutMarginsGuide 的底部。

let constraints = [
    toolbar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
    toolbar.trailingAnchor.constraint(equalTo: view.trailingAnchor),
    toolbar.bottomAnchor.constraint(equalTo: view.layoutMarginsGuide.bottomAnchor)
]
NSLayoutConstraint.activate(constraints)

这将使工具栏与 iOS 11+ 设备上的安全区域对齐,但您需要做最后一件事以使工具栏将其背景一直延伸到视图底部。为了在你的类中简单地符合UIToolbarDelegate,将自己设置为工具栏的委托,实现函数position(for: UIBarPositioning) -> UIBarPosition,并返回值.bottom。 UIToolbar 的 barPosition 的默认值是底部,因此在大多数用例中可能不需要最后一步。 完成此操作后,您应该会看到工具栏相对于安全区域布置其项目,同时将背景一直延伸到视图底部,就像您在 Mail 和 Safari 中看到的那样。

在这种情况下使用 layoutMarginsGuide 而不是 safeAreaLayoutGuide 的好处在于 layoutMarginsGuide 默认在安全区域内插入布局边距。因为您不直接引用安全区域,所以您的代码一直向后兼容到 iOS 9,而无需使用可用性检查。

【讨论】:

【参考方案3】:

我也遇到了这个问题。我的解决方案是使用通用 UIView 来说明底部 safeAreaInset,然后将工具栏添加为该视图的子视图。

private func addToolbar(_ toolbar: UIToolbar, toView view: UIView) 
    toolbar.frame = CGRect(x: 0,
                           y: 0,
                           width: view.frame.size.width,
                           height: 0)
    toolbar.sizeToFit() // This sets the standard height for the toolbar.

    // Create a view to contain the toolbar:
    let toolbarParent = UIView()
    toolbarParent.frame = CGRect(x: 0,
                                 y: view.frame.size.height - toolbar.frame.size.height,
                                 width: toolbar.frame.size.width,
                                 height: toolbar.frame.size.height)

    // Adjust the position and height of the toolbar's parent view to account for safe area:
    if #available(iOS 11, *) 
        toolbarParent.frame.origin.y -= view.safeAreaInsets.bottom
        toolbarParent.frame.size.height += view.safeAreaInsets.bottom
    

    toolbarParent.addSubview(toolbar)
    view.addSubview(toolbarParent)

【讨论】:

以上是关于自定义 UIToolbar 太靠近 iPhone X 上的主页指示器的主要内容,如果未能解决你的问题,请参考以下文章

UIToolBar 不在 iPhone 屏幕底部绘制

UIPageViewController 页面控件太靠近 iPhone X iOS 11 上的主页栏

苹果警告iPhone12别靠近心脏起搏器,这是啥原因?如何看待?

自定义 UIToolBar 的正确方法是啥?

如何使用包含彩色图像的按钮自定义 UIToolbar?

UIToolbar 的多个自定义背景