0

The aspect ratio for a 1080p hd video is 16:9 and to set a frame for the video in a cell so that it would fill it up completely I would use view.frame.width * 9 / 16:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    // the collection view is pinned to both sides of the vc with no spacing
    let width = collectionView.frame.width

    let videoHeight: CGFloat = width * 9 / 16

    return CGSize(width: width, height: videoHeight)
}

// inside the cell itself:

let videoHeight: CGFloat = self.frame.width * 9 / 16

contentView.addSubview(thumbnailImageView)
thumbnailImageView.topAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
thumbnailImageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
thumbnailImageView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true

// here is where I set the thumbnail's height
thumbnailImageView.heightAnchor.constraint(equalToConstant: videoHeight).isActive = true

This perfectly gives me:

enter image description here

The thing is I want a smaller version of the thumbnailImageView similar to youtube. I want to add the smaller thumbnailImageView on the left side of the screen but keep the aspect ratio the same.

enter image description here

The problem is when I attempted to do so I got a square instead of a rectangle. I divided the width of the cell by 3 and then multiplied it by 9 /16 but that isn't working. I used (width / 3) because I though it would keep the aspect ratio the same but reduce the size of the thumbnailImageView but it didn't work.

enter image description here

Where am I going wrong at?

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    // the collection view is pinned to both sides of the vc with no spacing
    let width = collectionView.frame.width

    let videoHeight: CGFloat = (width / 3) * 9 / 16

    return CGSize(width: width, height: videoHeight)
}

// inside the cell itself
let videoHeight = (self.frame.width / 3) * 9 / 16

contentView.addSubview(thumbnailImageView)
thumbnailImageView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8).isActive = true
thumbnailImageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8).isActive = true

// here is where I set the thumbnail's height and width
thumbnailImageView.heightAnchor.constraint(equalToConstant: videoHeight).isActive = true
thumbnailImageView.widthAnchor.constraint(equalToConstant: videoHeight).isActive = true
Lance Samaria
  • 17,576
  • 18
  • 108
  • 256

1 Answers1

3

You can use AVMakeRect(aspectRatio:insideRect:) function to get a scaled rectangle that maintains the specified aspect ratio within a bounding rectangle.

You can refer the API here.

By using the above API, your videoHeight value would be populated like below.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    // the collection view is pinned to both sides of the vc with no spacing
    let width = collectionView.frame.width
    let rect = AVMakeRect(aspectRatio: CGSize(width: 16, height: 9), insideRect: CGRect(origin: .zero, size: CGSize(width: width / 3, height: CGFloat.infinity)))
    let videoHeight: CGFloat = rect.size.height
    return CGSize(width: width, height: videoHeight)
}

And in cell, you can simply have height as follows.

let videoHeight = self.frame.height
Subramanian Mariappan
  • 3,736
  • 1
  • 14
  • 29
  • I never used that function before, Im trying it now based on this answer: https://stackoverflow.com/a/37996898/4833705. Gimme a couple of minutes – Lance Samaria May 12 '20 at 11:06
  • It's still coming out as a square but @matt in the comments said the issue is the math equation that I'm using. Let me get that part figured out first then I'll add it to the method that you posted. – Lance Samaria May 12 '20 at 11:13
  • Can you check the same with the snippet provided in the updated answer? And also do remove your videoHeight definition inside your function. – Subramanian Mariappan May 12 '20 at 11:17
  • I'm doing something wrong. I added the code snippet you posted to both the cell using self.frame.width and inside sizeForItem I used collectionView.frame.width (the cv is pinned to both sides of the vc). If I don't use the videoHeight then I won't be able to set the cell's height. When I added it I still got a square – Lance Samaria May 12 '20 at 11:21
  • Inside sizeForItem it should be collectionView.frame.width / 3. And can you log your frame and height obtained? – Subramanian Mariappan May 12 '20 at 11:27
  • My fault. I meant I added your code and inside sizeForItem I used *collectionView.frame.width / 3* and inside the cell I used *self.frame.width / 3* – Lance Samaria May 12 '20 at 11:35
  • Check my updated answer and let me know if you did the same. – Subramanian Mariappan May 12 '20 at 11:36
  • I originally had the same code in sizeForItem from your original answer and also inside the cell (using self.frame.width / 3). Now I just c+p your updated code inside sizeForItem and inside the cell I set only the thumbnail's width: **let videoHeight = self.frame.height; thumbnailImageView.heightAnchor.constraint(equalToConstant: videoHeight).isActive = true** Although the thumbnailImageView is now a rectangle it's now humongous. It looks like it's the size of the the first part of my question. In the cell I only set the height, top, and leading anchors, i left out the width. – Lance Samaria May 12 '20 at 11:43
  • In the snippet you posted about you'd set videoHeight to both height anchor and width anchor. Hope you updated that properly in your code. – Subramanian Mariappan May 12 '20 at 11:46
  • Value for your width anchor should have been self.frame.width / 3 – Subramanian Mariappan May 12 '20 at 11:47
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/213690/discussion-between-subramanian-mariappan-and-lance-samaria). – Subramanian Mariappan May 12 '20 at 11:48
  • You made my day.. +1 for you bro... thanks from Gujarat. – Vatsal Shukla Feb 23 '22 at 06:39