UILabel word wrap feature leaving space even when sufficient space available for the word

元气小坏坏 提交于 2020-05-24 05:07:16

问题


The problem coming even in storyboard.

The UILabel is having following properties:

  • numberOfLines = 0
  • lineBreakMode = .byWordWrapping
  • Constraints: Leading & Trailing 26 points to superview; vertically center.
  • Custom Font: Medium 17 Points.

As you can see the fourth word cannot fit in the first line and hence a problem by creating bad layout. If I remove the last word the sentence fits in one line completely or say the fourth word. If adding a word after it moves both of them to next line which leaves a lot of space. It should try to fit words without breaking or hyphenation as much as possible in one line. But clearly empty space is made even when word can fit.

You can recreate this in a new project and observe the issue.


回答1:


You may want to give this a try...

Subclass UITextView, disable scrolling, editing and selecting... set the textContainerInset = UIEdgeInsets.zero and textContainer.lineFragmentPadding = 0 to Zero.

Result:

Code (@IBDesignable so we can see it in IB / Storyboard):

@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
    }

}



回答2:


This code can be used in fixed width label and it will overcome that, also can get the height of the label

  private static func calculateLabelProperties() -> (String, CGFloat){

    let titleString = "Your string here"

        let wordArray = titleString.components(separatedBy: " ")
        var lineCount = 1//first line denoted by 1
        var tempWidth:CGFloat = 0
        var title = ""
        for (index,element) in wordArray.enumerated() {
            let width = calculateFontSize(title: element + " ", fontName: "your font name", fontSize: 17).width
            tempWidth = tempWidth + width

            //get the nextelement
            var nextElement = ""
            if wordArray.count > index + 1 {
                nextElement = wordArray[index + 1]
            }

            let nextElementWidth = calculateFontSize(title: nextElement, fontName: "your font name", fontSize: 17).width

            if tempWidth + nextElementWidth > 410 {//410 is labelwidth
                tempWidth = 0
                lineCount += 1
                title = "\(title)\(element)\n"
            } else {
                title = "\(title)\(element) "
            }
        }
        return (title, CGFloat(lineCount * 20))//20 is label sigle line height
    }

this code calculate font size

func calculateFontSize(title: String, fontName: String, fontSize: CGFloat) -> (width: CGFloat, height: CGFloat){
    let font = UIFont(name: fontName, size: fontSize)
    return (title.size(OfFont: font!).width, title.size(OfFont: font!).height)
}

get font size

extension String {
    func size(OfFont font: UIFont) -> CGSize {
        return (self as NSString).size(withAttributes: [NSAttributedString.Key.font: font])
    }
}


来源:https://stackoverflow.com/questions/56869332/uilabel-word-wrap-feature-leaving-space-even-when-sufficient-space-available-for

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!