How to determine height of UICollectionView with FlowLayout

前端 未结 13 2039
醉话见心
醉话见心 2020-11-28 18:01

I\'ve got an UICollectionView with an UICollectionViewFlowLayout, and i want to calculate its content size (for return in intrinsicContentSiz

相关标签:
13条回答
  • 2020-11-28 18:22

    In addition,you'd better calling reloadData before getting the height:

    theCollectionView.collectionViewLayout.collectionViewContentSize;
    
    0 讨论(0)
  • 2020-11-28 18:23

    Swift version of @user1046037:

    public class DynamicCollectionView: UICollectionView {
    
        override public func layoutSubviews() {
            super.layoutSubviews()
            if !bounds.size.equalTo(intrinsicContentSize) {
                invalidateIntrinsicContentSize()
            }
        }
    
        override public var intrinsicContentSize: CGSize {
            let intrinsicContentSize: CGSize = contentSize
            return intrinsicContentSize
        }
    }
    
    0 讨论(0)
  • 2020-11-28 18:24

    At viewDidAppear you can get it by:

    float height = self.myCollectionView.collectionViewLayout.collectionViewContentSize.height;
    

    Maybe when you reload data then need to calculate a new height with new data then you can get it by: add observer to listen when your CollectionView finished reload data at viewdidload:

    [self.myCollectionView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionOld context:NULL];
    

    Then add bellow function to get new height or do anything after collectionview finished reload:

    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary  *)change context:(void *)context
    {
        //Whatever you do here when the reloadData finished
        float newHeight = self.myCollectionView.collectionViewLayout.collectionViewContentSize.height;    
    }
    

    And don't forget to remove observer:

    [self.myCollectionView removeObserver:self forKeyPath:@"contentSize" context:NULL];
    
    0 讨论(0)
  • 2020-11-28 18:25

    Swift 4.2

    class DynamicCollectionView: UICollectionView {
        override func layoutSubviews() {
            super.layoutSubviews()
            if bounds.size != intrinsicContentSize {
                invalidateIntrinsicContentSize()
            }
        }
    
        override var intrinsicContentSize: CGSize {
            return self.contentSize
        }
    }
    
    0 讨论(0)
  • 2020-11-28 18:27

    It's too late to answer this question but I have recently gone through this issue.
    @lee's above answer help me a lot to get my answer. But that answer is limited to objective-c and I was working in swift.
    @lee With reference to your answer, allow me to let the swift user get this issue solved easily. For that, please follow below steps:

    Declare a CGFloat variable in declaration section:

    var height : CGFloat!
    

    At viewDidAppear you can get it by:

    height = self.myCollectionView.collectionViewLayout.collectionViewContentSize().height
    

    Maybe when you reload data then need to calculate a new height with new data then you can get it by: addObserver to listen when your CollectionView finished reload data at viewWillAppear:

    override func viewWillAppear(animated: Bool) {
            super.viewWillAppear(true)
            ....
            ....
            self.shapeCollectionView.addObserver(self, forKeyPath: "contentSize", options: NSKeyValueObservingOptions.Old, context: nil)
        }
    

    Then add bellow function to get new height or do anything after collectionview finished reload:

    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
            let newHeight : CGFloat = self.myCollectionView.collectionViewLayout.collectionViewContentSize().height
    
            var frame : CGRect! = self.myCollectionView.frame
            frame.size.height = newHeight
    
            self.myCollectionView.frame = frame
        }
    

    And don't forget to remove observer:

    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(true)
        ....
        ....
        self.myCollectionView.removeObserver(self, forKeyPath: "contentSize")
    }
    

    I hope this will help you to solve your issue in swift.

    0 讨论(0)
  • 2020-11-28 18:32

    Swift 4.2, Xcode 10.1, iOS 12.1:

    For some reason, collectionView.contentSize.height was appearing smaller than the resolved height of my collection view. First, I was using an auto-layout constraint relative to 1/2 of the superview's height. To fix this, I changed the constraint to be relative to the "safe area" of the view.

    This allowed me to set the cell height to fill my collection view using collectionView.contentSize.height:

    private func setCellSize() {
        let height: CGFloat = (collectionView.contentSize.height) / CGFloat(numberOfRows)
        let width: CGFloat = view.frame.width - CGFloat(horizontalCellMargin * 2)
    
        let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
        layout.itemSize = CGSize(width: width, height: height)
    }
    

    Before

    After

    0 讨论(0)
提交回复
热议问题