11工具栏UIBarButtonItem

11工具栏UIBarButtonItem

本文介绍了使用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中,UI工具栏和UI导航栏都有
错综复杂,并表示支持自动布局。

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

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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 05:22