在这种特殊情况下,我实际上很困惑。我对 UINavigationBar 进行了子类化,注意到 Apple 过时的示例代码,意识到 sizeToFit 永远不会被调用和覆盖intrinsicContentSize
并layoutSubviews
计算必要的高度。在根据我提供的自定义视图计算高度时,一切都很好(我systemLayoutSizeFittingSize
用于根据自定义内容视图/标题视图动态计算高度)。
奇怪的是,当我尝试为任何更改设置动画时,我可以为 custom 中的更改设置动画titleView
,但是当通过 重新加载intrinsicContentSize 时invalidateIntrinsicContentSize()
,视图框架更改不会设置动画。它啪啪啪。
示例代码:
let delta = destinationTextFieldContainerView.frame.minX - originTextFieldContainerView.frame.minX + originTextFieldContainerView.frame.height
textContainersSeparatorConstraint.constant = -delta
UIView.animateWithDuration(2, delay: 2, options: UIViewAnimationOptions.CurveEaseIn, animations: {
self.customContainerNavigationBar.invalidateIntrinsicContentSize()
self.customContainerNavigationBar.layoutIfNeeded()
}) { (_) in
self.customContainerNavigationBar.invalidateIntrinsicContentSize()
}
一个约束值更改将动画化,但不幸的是(因为 navBars 不依赖自动布局)似乎更新框架存在问题。我尝试在使固有大小无效之前直接更新框架,但没有成功。我还尝试了高度约束,将其列在具有不同时间偏移的关键帧动画中,在不同的时间点使布局无效,但都没有成功。任何帮助将不胜感激。
可以在这里找到调整大小的代码:
override func intrinsicContentSize() -> CGSize {
var navigationBarSize = super.intrinsicContentSize()
navigationBarSize.width = superview?.frame.width ?? 0
guard let titleView = navigationItem?.titleView else {
return navigationBarSize
}
let fittingSize = CGSize(width: navigationBarSize.width, height: UILayoutFittingCompressedSize.height)
let titleViewSize = titleView.systemLayoutSizeFittingSize(fittingSize)
navigationBarSize.height = max(titleViewSize.height, 44)
navigationBarSize.width = UIViewNoIntrinsicMetric
return navigationBarSize
}
override func layoutSubviews() {
super.layoutSubviews()
guard let navigationItem = navigationItem, titleView = navigationItem.titleView else {
return
}
var navigationBarSize = bounds.size
navigationBarSize.width = superview?.frame.width ?? 0
var fittingSize = CGSize(width: navigationBarSize.width, height: UILayoutFittingCompressedSize.height)
if let leftBarButtonItem = navigationItem.leftBarButtonItem, leftButtonCustomView = leftBarButtonItem.customView {
fittingSize.width -= leftButtonCustomView.frame.width + leftButtonCustomView.frame.origin.x + 22
}
let titleViewSize = titleView.systemLayoutSizeFittingSize(fittingSize, withHorizontalFittingPriority: UILayoutPriorityRequired, verticalFittingPriority: UILayoutPriorityDefaultLow)
titleView.frame = CGRect(origin: CGPoint(x: titleView.frame.origin.x, y: 0), size: titleViewSize)
titleView.setNeedsLayout()
titleView.layoutIfNeeded()
if let leftBarButtonItem = navigationItem.leftBarButtonItem, leftButtonCustomView = leftBarButtonItem.customView {
var customViewFrame = CGRect(origin: CGPoint.zero, size: navigationBarSize)
let customViewSize = leftButtonCustomView.systemLayoutSizeFittingSize(customViewFrame.size, withHorizontalFittingPriority: UILayoutPriorityDefaultLow, verticalFittingPriority: UILayoutPriorityDefaultLow)
customViewFrame.size = customViewSize
leftButtonCustomView.frame = customViewFrame
leftButtonCustomView.setNeedsLayout()
leftButtonCustomView.layoutIfNeeded()
}
invalidateIntrinsicContentSize()
}