Home > OS >  Table view cell labels are inconsistent in line break
Table view cell labels are inconsistent in line break

Time:09-17

I have a custom table view cell with a label inside. I've noticed that every seventh cell's label breaks first line way too early. All the cells on the screenshot have the same String subsequence (black and red ovals) at the beginning of its label's text. The mid-cell is the seventh one, as you could have guessed. If I scroll 7 cells down, the result is going to be the same

label configuration:

descriptionLabel.numberOfLines = 0
descriptionLabel.lineBreakMode = .byWordWrapping

I have no clue what to do to fix the issue, begging for your help. Thanks in advance!

screenshot

CodePudding user response:

An "orphan" is a single word on a line at the end of a paragraph. In typography, it is considered "bad layout" to leave a word dangling at the end.

So, Apple has coded UILabel to avoid "orphans."

If you don't mind orphans in your labels, UITextView does not enforce that -- so you could use a UITextView (with editing and scrolling disabled).

As you can see in this image, though:

enter image description here

UITextView has default "insets" for the text from the actual frame.

So, here is an @IBDesignable subclass that removes the insets:

@IBDesignable
class TextViewLabel: UITextView {
    
    override init(frame: CGRect, textContainer: NSTextContainer?) {
        super.init(frame: frame, textContainer: textContainer)
        commonInit()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }
    
    func commonInit() -> Void {
        isScrollEnabled = false
        isEditable = false
        isSelectable = false
        textContainerInset = UIEdgeInsets.zero
        textContainer.lineFragmentPadding = 0
    }
    
}

Edit for clarification...

Here are three default UILabel, all the exact same width:

enter image description here

Note that with label A, there is plenty of room at the end of the first line for the word "an", but it gets wrapped to the second line to prevent an orphan -- that is, prevent a single word on the second line.

With label B, the word "an" stays on the first line, because word wrapping results in two words on the second line.

As we see with label C though, if the text wraps onto more than two lines the UILabel will allow an orphan -- a single word on the last line.

By replacing the default UILabel with the TextViewLabel subclass, we can force the two-line wrapping to ignore the "orphan" wrapping:

enter image description here

  • Related