BigBoy1337
BigBoy1337

Reputation: 5003

How to set NSLayoutConstraint constant in a collectionView cell?

In my storyboard I have a set of constraints for the subview (called Thumbnail) in a cell

enter image description here

Then in my custom collectionView cell:

class PostViewCell: UICollectionViewCell {

var portrait: Bool? {
    didSet {
        if portrait == true {
            print(self.bounds.height)
            thumbnailWidthConstraint.constant = self.bounds.width
            thumbnailHeightConstraint.constant = self.bounds.height/2
            thumbnailHeightConstraint.isActive = true
        } else {
            thumbnailWidthConstraint.constant = self.bounds.width/2
            thumbnailHeightConstraint.constant = self.bounds.height
        }
        self.layoutIfNeeded()
    }
}
@IBOutlet weak var thumbnailCenterYConstraint: NSLayoutConstraint!
@IBOutlet weak var thumbnailWidthConstraint: NSLayoutConstraint!
@IBOutlet weak var thumbnailHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var thumbnailCenterXConstraint: NSLayoutConstraint!

override func layoutSubviews() {
    if self.bounds.width > self.bounds.height {
        portrait = false
    } else {
        portrait = true
    }
    super.layoutSubviews()
}

}

My goal is to change the height and width of the thumbnail like you see in the didSet method of the portrait variable. However, so far this seems unsuccessful. It prints a self.bounds.height of 536 and in the app it seems to be this height, not half the height as I am trying to set in the constraint. What step am I missing? Why isn't this working? Thanks!

Edit: In my view controller that contains the collectionView cells I have:

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    postsCollectionView.collectionViewLayout.invalidateLayout()
    postsCollectionView.layoutIfNeeded()
    super.viewWillTransition(to: size, with: coordinator)
}

this collection view is called "postsCollectionView" in my view controller. Additionally, I have this:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    if collectionView == timelineCollectionView {
        return CGSize(width: CGFloat(2.5), height: collectionView.bounds.height)
    } else {
        return CGSize(width: collectionView.bounds.size.width, height: collectionView.bounds.size.height)
    }
}

Thus when I rotate the phone and the collectionView becomes wider than it is tall, so does the cell inside. This hopefully sets the cell to re-layout subviews and alter the constraints as I have defined.

Upvotes: 0

Views: 940

Answers (1)

Shehata Gamal
Shehata Gamal

Reputation: 100533

You may miss re-layout after changing the constant

var portrait: Bool? {
    didSet {
        if portrait == true {
            print(self.bounds.height)
            thumbnailWidthConstraint.constant = self.bounds.width
            thumbnailHeightConstraint.constant = self.bounds.height/2
            thumbnailHeightConstraint.isActive = true
        } else {
            thumbnailWidthConstraint.constant = self.bounds.width/2
            thumbnailHeightConstraint.constant = self.bounds.height
        }

        self.layoutIfNeeded() // or  self.contentView.layoutIfNeeded() 
    }
}

You need also to respond to system orientation changes

func viewWillTransition(to size: CGSize, 
               with coordinator: UIViewControllerTransitionCoordinator) {
  collectionView.collectionViewLayout.invalidateLayout()
  collectionView.layoutIfNeeded()
}

Upvotes: 1

Related Questions