带有customView的自动布局iOS 11工具栏UIBarButtonItem [英] Auto Layout iOS 11 Toolbar UIBarButtonItem with customView

查看:31
本文介绍了带有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 上没有找到真正为我解决问题的答案,所以我对其进行了调查,并提出了一个(诚然有点老套的)解决方案,我想与您分享.

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 的子视图.这可能是 UIBarButtonItem 中包含 customView 的结果.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.可能 return 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.

查找"功能是对序列的扩展.它执行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天全站免登陆