0

I set sections for my horizontal UICollectionView. I want my cell item in second rows in each section to be double width of items in first row. This is what i set:

func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 2
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    if section == 0 {
        return 2
    }
    return 1
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { //1.7, 2.7
    if indexPath.row == 0 {
        return CGSize(width: collectionView.frame.size.width/2,
        height: collectionView.frame.size.height/2)
    }
    return CGSize(width: collectionView.frame.size.width,
                  height: collectionView.frame.size.height/2)

}

But this is the end result:

enter image description here

How i can get rid of spaces in smaller size items and layout them nicely?

Note: Numbers on pictures represent section and row (0 1 -> Section 0, Row 1)

This is what i want to achieve:

enter image description here

Umit Kaya
  • 5,771
  • 3
  • 38
  • 52

2 Answers2

2

First: if you use a storyboard, make sure you add collection view's constraints properly to its super view.

Second: Add collection view cell's constraints.

Third: From storyboard's size inspector, change collection view's estimate size to none.

Fourth: Add UICollectionViewDelegateFlowLayout in your viewcontroller

Fifth: Add those following code:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    if indexPath.section == 0 {
        return CGSize(width: (collectionView.frame.size.width - 10)/2,
        height: (collectionView.frame.size.height - 10)/2) // your desired height
    }
    return CGSize(width: (collectionView.frame.size.width - 10),
                  height: (collectionView.frame.size.height - 10)/2)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
            return UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 0.0
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
            return 5
}
Asif Newaz
  • 557
  • 7
  • 17
  • Thank you for the detailed answer. This is setting layout sizes correctly but larger cell in width is placing on top which is at section 2. So it looks like this: Section 0, index 0: small, Section 0, index 1: small, Section 1, index 0: large.. What i need is: Section 0, index 0: small, Section 0, index 1: large, Section 1, index 0: small. So all items on top has to be small and all at bottom should be large. Am i clear? – Umit Kaya May 05 '20 at 15:06
  • Well, this is confusing, first of all, how many sections do you have? according to your question, there are 2 sections, then how can you get section 2. There will only section 0 and section 1. – Asif Newaz May 05 '20 at 16:27
  • Anyways, my solution was according to your second image. Try to debug inside _sizeForItemAt_ method according to your section. you can check this [link] [https://developer.apple.com/documentation/uikit/uicollectionview/customizing_collection_view_layouts] – Asif Newaz May 05 '20 at 16:35
  • Yes you are right, it is section 0 and 1. But the mistake in your answer is; setting first row as large in section 1. In my second image, large one is row1. Row 0 in all sections are always small image. – Umit Kaya May 05 '20 at 16:42
  • Just for your reference : this is what i got after your code applied: https://ibb.co/0fPJcZV Black spot is right edge of simulator, pls ignore.. @Asif Newaz – Umit Kaya May 05 '20 at 17:09
  • Ok, You want (section 0, row 0) and (section 1, row 0) horizontally, where (section 0 row 1) below them right?. if you use two sections then this is not possible I guess. I will suggest using one section and 3 items per section. Then insert your desired data inside the cell at item method. – Asif Newaz May 05 '20 at 17:18
  • and change the method by replacing these code `func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { if indexPath.row < 2 { return CGSize(width: (collectionView.frame.size.width - 10)/2, height: (collectionView.frame.size.height - 10)/2) // your desired height } return CGSize(width: (collectionView.frame.size.width - 10), height: (collectionView.frame.size.height - 10)/2) }` – Asif Newaz May 05 '20 at 17:18
  • It is placing as we expect except the space on small cells: https://ibb.co/fp8Kqb7 If the spaces are filled by next item, it would fit perfectly, but it looks like it marks the column based on big item and doesnt let other items to stick in :/ By the way, thanks for following up. I voted up your answer but not marked yet as still trying to find out a way out of this.. – Umit Kaya May 05 '20 at 17:59
  • @UmitKaya thanks. if you have a solution let me know. thanks – Asif Newaz May 05 '20 at 20:12
  • i have ended up adding all items in one collection view cell by custom design and show/hide them by number of items available, so every more 3 items will take another section. Its not the best approach i know but that works at the moment. Thank you again for your valuable inputs. – Umit Kaya May 06 '20 at 13:57
0

Replace indexPath.row with indexPath.section.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { //1.7, 2.7
    if indexPath.section == 0 {
        return CGSize(width: collectionView.frame.size.width/2,
        height: collectionView.frame.size.height/2)
    }
    return CGSize(width: collectionView.frame.size.width,
                  height: collectionView.frame.size.height/2)

}




Hayk Brsoyan
  • 186
  • 5
  • This will happen: https://ibb.co/0fPJcZV But here we want to have different size for the same section's row 1 – Umit Kaya May 05 '20 at 20:15