作者:哈罗xeh_406 | 来源:互联网 | 2023-01-15 13:21
最近在我们的项目中,使用customView的UIBarButtonItem出现了问题.在iOS 11之前,我们通过灵活的间距项目进行了布局.这不再起作用,因此没有显示任何内容.
因为我没有在SO上找到真正为我解决问题的答案,所以我调查了它,想出了一个我想与你分享的(当然是一种hacky)解决方案.
也许它可以帮助你或你有一些反馈.这是混合的objc和swift代码,希望你不要介意.
1> lucasl..:
如WWDC视频更新iOS 11应用程序所示:
"现在在iOS 11中,UI工具栏和UI导航栏都有复杂的表达支持自动布局."
所以我的第一步是在自定义视图本身上使用布局约束:
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的宽度.
所以它看起来像这样:
contentView |<-fullWidth-------->|
stackView |<-reducedWidth->|
customView |<-reducedWidth->|
让我好奇的是,customView不是stackView的子视图.这可能是由于CustomView包含在UIBarButtonItem中的结果.customView上的任何(附加)约束保持不变(或崩溃,因为视图不在同一层次结构中).
在学习了所有这些之后,我在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
会做同样的事,但我想确定.
然后设置布局约束并且瞧:它在全宽度下工作.
我希望有人可能觉得这很有用.如果有评论:我对这个问题的反馈非常开放.也许我错过了一些东西,所有这一切都没有必要.
编辑:'find'功能是Sequence的扩展.它确实'filter.first',看起来像这样:
extension Sequence {
func find(_ isIncluded: (Self.Element) throws -> Bool) rethrows -> Self.Element? {
return try filter(isIncluded).first
}
}