0

Right now, i'm facing an issue.

I manage to wrap the cell's content view to its label, but there's some spacing which doesn't fit to the design. There's some spaces available between the cell

Here's my code

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

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

    let hastag = Hastag.fetchHastag()[indexPath.row]

    let approximateWidth = view.frame.width - 20
    let size = CGSize(width: approximateWidth, height: 28)
    let attribute = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 12)]

    let estimatedFrame = NSString(string: hastag.hastag).boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: attribute, context: nil)

    return CGSize(width: estimatedFrame.width + 20, height: 26)

}

Below is the result

enter image description here

And this is what i want to achieve, it will be something like this

enter image description here

UPDATE

Here is my full code of collection view data source and delegate. Hastag.hastag is type of string

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return Hastag.fetchHastag().count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "hastagCell", for: indexPath) as! HastagCollectionViewCell

    cell.hastag = Hastag.fetchHastag()[indexPath.row]

    return cell
}

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

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

    let hastag = Hastag.fetchHastag()[indexPath.row]

    let approximateWidth = view.frame.width - 20
    let size = CGSize(width: approximateWidth, height: 28)
    let attribute = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 12)]

    let estimatedFrame = NSString(string: hastag.hastag).boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: attribute, context: nil)

    return CGSize(width: estimatedFrame.width + 16, height: 26)

}
Jason
  • 33
  • 7

3 Answers3

0

You can use AlignedCollectionViewFlowLayout, its not a library just one file. Just add this file to your project and from your UICollectionView xib just set the flow layout as AlignedCollectionViewFlowLayout. It is very easy to use. Please check the below link.

https://github.com/mischa-hildebrand/AlignedCollectionViewFlowLayout

vivekDas
  • 1,210
  • 8
  • 11
0

You can use the size(withAttributes:) function of a NSString to give you the CGSize of a string with a specific font and size.

Assuming that Hastag.hastag is a String I think the following should work:

extension YourViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let hastag = Hastag.fetchHastag()[indexPath.row]
        let title = hastag.hastag as NSString
        let titleSize = title.size(withAttributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 12)])
        return CGSize(width: titleSize.width + 20, height: 26)
    }
}

Note that your ViewController must implement the UICollectionViewDelegateFlowLayout protocol and you must set your ViewController as the delegate for the UICollectionView for this to work.

Hope that helps.

pbodsk
  • 6,371
  • 3
  • 20
  • 47
  • thank you for answering, but your code returns the same as my code – Jason Jul 27 '18 at 07:06
  • hmm...then there must be something else different in your setup...because the above work for me :) Could you show me how you have defined the layout maybe? – pbodsk Jul 27 '18 at 07:08
  • check my updates please ;). on the storyboard, i set constraint for my collection view 8,8,16,16 (top, bottom, trailing, leading) in case you need to know that – Jason Jul 27 '18 at 07:26
  • @Jason I've updated my answer, make sure that you implement the `UICollectionViewDelegateFlowLayout` and add your view controller as a `delegate` (see this fine answer for instance: https://stackoverflow.com/a/12925529/4063602) – pbodsk Jul 27 '18 at 08:07
  • OK. And you can see that your method is called if you place an breakpoint in it? – pbodsk Jul 27 '18 at 09:23
  • sorry, what do you mean? – Jason Jul 27 '18 at 09:24
  • If you add a breakpoint in your sizeForItemAt: method, and then run your code, is the breakpoint then hit? If it isn’t then that is why it isn’t working – pbodsk Jul 27 '18 at 09:32
  • It must be hit the method. Because if it doesn't, then the cell doesn't resize to the label inside of it. But I'll try to put the breakpoint. I'll give you the info soon – Jason Jul 27 '18 at 09:46
0

After several try, i finally give up on customizing cell size and instead i'm using the library TagListView

Jason
  • 33
  • 7