Wrong result when dynamically changing the height of the CollectionView to adapt to content size

主宰稳场 提交于 2021-01-29 11:29:25

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!