使用customView自动布局iOS 11工具栏UIBarButtonItem [英] Auto Layout iOS 11 Toolbar UIBarButtonItem with customView

查看:757
本文介绍了使用customView自动布局iOS 11工具栏UIBarButtonItem的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近在我们的项目中,使用customView的UIBarButtonItem出现问题。在iOS 11之前,我们通过灵活的间距项目进行了布局。这不再有效了,所以没有显示任何内容。

Recently in our project there was a problem with a UIBarButtonItem that was using a customView. Before iOS 11 we did the layout via flexible spacing items. This didn't work anymore and so nothing was displayed.

因为我在SO上找不到真正为我解决问题的答案,所以我调查了它并想出了一个(我承认有点hacky)解决方案,我想与你分享。

Because I didn't find an answer here on SO that really solved the issue for me, I looked into it and came up with a (admittedly kind of hacky) solution I wanted to share with you.

也许它可以帮助您或您有一些反馈。这是混合的objc和swift代码,希望你不介意。

Maybe it can help you or you have some feedback. This is mixed objc and swift code, hope you don't mind.

推荐答案

如WWDC视频所示更新适用于iOS 11的应用

现在在iOS 11中,UI工具栏和UI导航栏都有
错综复杂,并表示支持自动布局。

"And so now in iOS 11, UI toolbar and UI navigation bar both have intricate and express support for auto layout."

所以我的第一步是在自定义视图本身上使用布局约束:

So my first step was to use layout constraints on he custom view itself:

    UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:customView];
    [barButtonItem.customView.widthAnchor constraintEqualToConstant:375].active = YES;
    [barButtonItem.customView.heightAnchor constraintEqualToConstant:44].active = YES;

这导致工具栏显示customView。问题在于视图的左右两侧存在差距。你可以看到它。
所以我查看了View Hierarchy Debugging工具并意识到,工具栏上有一个UIToolbarContentView。这个contentView有正确的大小(特别是宽度),我开始怀疑。我查看了contentView唯一的子视图,它是一个UIBarButtonStackView。这个stackView以某种方式限制了我的customView的宽度。

This resulted in the toolbar showing the customView. The problem was that left and right of the view, there was a gap. And you could see it. So I looked in the View Hierarchy Debugging tool and realized, there is a UIToolbarContentView on the toolbar. This contentView had the right size (especially width) and I began wondering. I looked at the only subview the contentView had and it was a UIBarButtonStackView. This stackView was somehow limiting my customView in terms of width.

所以它看起来像这样:

contentView |<-fullWidth-------->|
stackView     |<-reducedWidth->|
customView    |<-reducedWidth->|

让我好奇的是,customView不是stackView的子视图。这可能是由于CustomView包含在UIBarButtonItem中的结果。 customView上的任何(附加)约束保持不变(或崩溃,因为视图不在同一层次结构中)。

What made me curios was, that the customView is not a subview of the stackView. This is probably a consequence of the customView being included in UIBarButtonItem. Any (additional) constrains on the customView remained without change (or crashes because the views aren't in the same hierarchy).

在学习了所有这些之后,我添加了一个扩展名到UIToolbar:

After learing all this, I added an extension to the UIToolbar:

extension UIToolbar {
    private var contentView: UIView? {
        return subviews.find { (view) -> Bool in
            let viewDescription = String(describing: type(of: view))
            return viewDescription.contains("ContentView")
        }
    }

    private var stackView: UIView? {
        return contentView?.subviews.find { (view) -> Bool in
            let viewDescription = String(describing: type(of: view))
            return viewDescription.contains("ButtonBarStackView")
        }
    }

   func fitContentViewToToolbar() {
        guard let stackView = stackView, let contentView = contentView else { return }
        stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
        stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
        stackView.widthAnchor.constraint(equalTo: contentView.widthAnchor).isActive = true

    }
}

所以它的作用是:
它通过比较名称从子视图中获取contentView ContentView并通过在contentView上执行相同操作来获取stackView。
可能返回subviews.first 也会这样做,但我想确定。

So what it does is this: It gets the contentView from the subviews by comparing the names to "ContentView" and gets the stackView by doing the same on the contentView. Probably a return subviews.first would do the same, but I wanted to be sure.

然后设置布局约束并且瞧:它在全宽度下工作。

Then the layout constraints are set and voila: it works in the full width.

我希望有人可能会觉得这很有用。如果有评论:我对这一点的反馈非常开放。也许我错过了一些东西,但这一切都没有必要。

I hope someone may find this useful. If there's comments: I'm very open to feedback on this one. Maybe I missed something and all this isn't even necessary.

编辑:'find'功能是Sequence的扩展。它确实是'filter.first',看起来像这样:

The 'find' function is an extension to Sequence. It does 'filter.first' and looks like this:

extension Sequence {
    func find(_ isIncluded: (Self.Element) throws -> Bool) rethrows -> Self.Element? {
        return try filter(isIncluded).first
}

}

这篇关于使用customView自动布局iOS 11工具栏UIBarButtonItem的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆