问题
In my DetailViewController
, I have two collectionViews
and I am trying to change their height dynamically. I can successfully achieve this by changing the two heigh constraints IBOutlets
with observers in DetailViewController
. However, it does not work if, from DetailViewController
I push another ViewController and then I go back.
This is the code in "DetailViewController"
@IBOutlet weak var deadlineCollectionViewHeight: NSLayoutConstraint!
@IBOutlet weak var tasksCollectionViewHeight: NSLayoutConstraint!
private var CVcontentSizeObservation: [NSKeyValueObservation]?
private var initialCollectionViewsHeight: InitialCollectionViewsHeight?
override func viewDidLoad() {
super.viewDidLoad()
initialCollectionViewsHeight = InitialCollectionViewsHeight(deadlines:
deadlineCollectionViewHeight.constant, tasks: tasksCollectionViewHeight.constant)
observeCollectionView()
}
private func observeCollectionView(){
CVcontentSizeObservation = [
deadlinesCollectionView.observe(\.contentSize, options: .new, changeHandler: {[weak self] (cv, _) in
guard let self = self else { return }
if cv.collectionViewLayout.collectionViewContentSize.height < self.initialCollectionViewsHeight!.deadlines{
self.deadlineCollectionViewHeight.constant = cv.collectionViewLayout.collectionViewContentSize.height
}
}),
tasksCollectionView.observe(\.contentSize, options: .new, changeHandler: {[weak self] (cv, _) in
guard let self = self else { return }
if cv.collectionViewLayout.collectionViewContentSize.height < self.initialCollectionViewsHeight!.tasks{
self.tasksCollectionViewHeight.constant = cv.collectionViewLayout.collectionViewContentSize.height
}
})
]
}
private struct InitialCollectionViewsHeight{
var deadlines: CGFloat
var tasks: CGFloat
}
The problem
This works fine if from the home VC I push the DetailViewController
, but if from there I push another VC and then go back, I get a wrong result.
The first image shows the correct behavior after the DetailViewController
is initially pushed. However, if I press on the "Edit Button" button and a new VC is pushed, I get a wrong result after I dismiss it and pop the VC from the stack (i.e: I go back to DetailViewController
), as seen in the second image
回答1:
From what I understand, you are trying to make collection views to fit their height. Using constraint approach may bring some problems, due to UICollectionViewLayout behaviour.
I would recommend using this approach:
class AutoSizingCollectionView : UICollectionView
{
override func layoutSubviews() {
super.layoutSubviews()
if (self.bounds.size.equalTo(self.intrinsicContentSize)) {
self.invalidateIntrinsicContentSize()
}
}
override var intrinsicContentSize: CGSize
{
return self.collectionViewLayout.collectionViewContentSize
}
}
Exchange your CollectionViews with AutoSizingCollectionView
class and they will scale their height to their content size automatically using IntrinsicContentSize
method. It will allow you to easily pin bottom collection view to bottom of the first one.
I hope that solves root of your problem.
来源:https://stackoverflow.com/questions/65587680/wrong-result-when-dynamically-changing-the-height-of-the-collectionview-to-adapt