Multiline UILabel Text inside UICollectionView Cell

I have setup UICollection View Cell with two UI Label, first for heading & second for content.


But I am trying to have multiline text inside UILabel for content. But nothing is working.


I am using the following code at "cellForItemAt indexPath". but it fails to work or apply.


cell.descriptionUILabel.numberOfLines = 0
cell.descriptionUILabel.textAlignment = .left
cell.descriptionUILabel.sizeToFit()
cell.descriptionUILabel.lineBreakMode = .byWordWrapping
cell.descriptionUILabel.baselineAdjustment = .alignCenters
cell.descriptionUILabel.contentMode = .topLeft

Replies

I get the same problem.


Then I made the label frame higher and it worked (system font is 17, minimal height for 2 lines is 42).

        let label = UILabel(frame: CGRect(x: 5, y: 0, width: 35, height: 45))          // Not OK if height is 40
        label.text = "text On 2 lines"

        label.lineBreakMode = .byWordWrapping
        label.numberOfLines = 0
        cell.contentView.insertSubview(label, at: 1)


When replacing UILabel by UITextView, it works directly.

As you suggested I used UITextView instead of UILabel. And removed UILabel completely.


But now the text is cropping at top...!!!


Is there any way to change line-height as per my choice? And fit text to the height of UITextView...

What do you mean precisely "text is cropping at top" ?

How do you want to " fit text to the height of UITextView..." ?


If you use AttributedText, you can set paragraph style.

Or, if you change the UITextView frame, can you solve the problem ?

I have added UITextView to UICollectionView Cell, UITextView has 130 px height.


I assign text to UITextView with string array.


It scrolls to bottom at load then I have to scroll to the top to see starting of the string text.


How to fix all multiline text to UITextView height without scrolling?


I am using the following code but it is not working:


cell.descriptionUITextView.sizeToFit()
cell.descriptionUITextView.contentMode = .topLeft
cell.descriptionUITextView.isScrollEnabled = false
cell.descriptionUITextView.textContainer.lineBreakMode = .byWordWrapping

You should remove

cell.descriptionUITextView.isScrollEnabled = false


If I understand correctly your issue, you could add:


let newPosition = textField.beginningOfDocument
textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition)


have a look here

https://stackoverflow.com/questions/34922331/getting-and-setting-cursor-position-of-uitextfield-and-uitextview-in-swift

Sorry, you understand it wrong...


I want to fit text in UITextView... I don't want it to be scrolled or interact...

I tried with sizeToFit.


It does adapts the height, but not the width of the textView.

Probably because textWrap is automatic here.


So, you may have to recompute and adapt width.

I found some way to achieve it:


        cell.descriptionUITextView.isUserInteractionEnabled = false     //. if need  to allow to tap in cell without editing
        var ok = true
        repeat {
            let neededSize = cell.descriptionUITextView.sizeThatFits(lcell.descriptionUITextView.frame.size)
            ok = neededSize.height <=cell.descriptionUITextView.frame.size.height || cell.descriptionUITextView.frame.size.width >= cell.frame.width - 10
          // increment 10 by 10
            if !ok {
                cell.descriptionUITextView.frame.size.width += 10
            }
        } while !ok


See interesting discussion here:

h ttps://medium.com/@how_noobs_think/how-to-resize-a-textview-to-fit-its-content-re-sizing-textview-based-on-its-contentsize-fe4f5dab461e

I am using your above code inside "cellForItemAt indexPath" but it is not making any difference...


But I have given fixed height for cell in "sizeForItemAt indexPath"


My "sizeForItemAt indexPath" look something like this:


func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        var sizeArea = CGSize()
        let spacing = self.view.frame.size.width - 10
        let itemWidth = spacing / 1
        let itemHeight = CGFloat(200.0)
        sizeArea = CGSize(width: itemWidth, height: itemHeight)
        return sizeArea
    }

I am using ias follows, directly in cellForItemAt, and it works:



    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
      
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FirstCollectionCell", for: indexPath) as! FirstCollectionViewCell
        let label = UITextView(frame: CGRect(x: 5, y: 0, width: 30, height: 40))

        label.text = "text On 2 lines with a long text"
        label.isUserInteractionEnabled = false
        var ok = true
        repeat {
            let neededSize = label.sizeThatFits(label.frame.size)
            ok = neededSize.height <= label.frame.size.height || label.frame.size.width >= cell.frame.width - 10
            if !ok {
                label.frame.size.width += 10
            }
        } while !ok
        cell.contentView.insertSubview(label, at: 1)
        label.sizeToFit()
        return cell
    }

Maybe you could reset the height when you create the UITextView.


So, if you don't need it elsewhere, I would remove:


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

Did you solve your issue ?