Home > other >  Swift UILabel linespacing for single line text
Swift UILabel linespacing for single line text

Time:01-21

I want to increase padding inside UILabel cell (top and bottom),with modifying line height priority. Currently i use that extension:

func setLineSpacing(lineSpacing: CGFloat = 0.0, lineHeightMultiple: CGFloat = 0.0) {

          guard let labelText = self.text else { return }

          let paragraphStyle = NSMutableParagraphStyle()
          paragraphStyle.lineSpacing = lineSpacing
          paragraphStyle.lineHeightMultiple = lineHeightMultiple

          let attributedString: NSMutableAttributedString
          if let labelattributedText = self.attributedText {
              attributedString = NSMutableAttributedString(attributedString: labelattributedText)
          } else {
              attributedString = NSMutableAttributedString(string: labelText)
          }

          // (Swift 4.2 and above) Line spacing attribute
          attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range:NSMakeRange(0, attributedString.length))
    
          print("attributed string \(attributedString)")
          self.attributedText = attributedString
      }

My problem is, it doesn't modify vertical gaps when number of lines of UILabel is single. Therefore i failed to achieve specific offsets corresponding to UI design when there is specific line height for label is set.

CodePudding user response:

The paragraphStyle is interested lines in Label not the whole component. You are setting some properties between this lines(cells) . So when number of lines is 1 , There is nothing to affect.If you want to give top and bottom between text(not cells) and UILabel component, you must give top and bottom space to Label .

Example Class

class labelClass : UILabel{

var padding = UIEdgeInsets()

required init?(coder: NSCoder) {
    super.init(coder: coder)
}

func setLineSpacing(lineSpacing: CGFloat = 0.0, lineHeightMultiple: CGFloat = 0.0) {
    padding = UIEdgeInsets(top: lineSpacing, left: 0, bottom: lineSpacing, right: 0)
          guard let labelText = self.text else { return }

          let paragraphStyle = NSMutableParagraphStyle()
    
          paragraphStyle.lineSpacing = lineSpacing
          paragraphStyle.lineHeightMultiple = lineHeightMultiple
          let attributedString: NSMutableAttributedString
          if let labelattributedText = self.attributedText {
              attributedString = NSMutableAttributedString(attributedString: labelattributedText)
          } else {
              attributedString = NSMutableAttributedString(string: labelText)
          }

          // (Swift 4.2 and above) Line spacing attribute
          attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range:NSMakeRange(0, attributedString.length))
    
    
          print("attributed string \(attributedString)")
    
          self.attributedText = attributedString
    
 

      }

override func drawText(in rect: CGRect) {
    super.drawText(in: rect.inset(by: padding))
}

override var intrinsicContentSize : CGSize {
    let superContentSize = super.intrinsicContentSize
    let width = superContentSize.width   padding.left   padding.right
    let heigth = superContentSize.height   padding.top   padding.bottom
    return CGSize(width: width, height: heigth)
}

}

According to Comment:

You can get current text numberOfLines count by using link

extension UILabel {
func calculateMaxLines() -> Int {
    let maxSize = CGSize(width: frame.size.width, height: CGFloat(Float.infinity))
    let charSize = font.lineHeight
    let text = (self.text ?? "") as NSString
    let textSize = text.boundingRect(with: maxSize, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil)
    let linesRoundedUp = Int(ceil(textSize.height/charSize))
    return linesRoundedUp
}
}

And do operation when numberOfLines is 1

 func setLineSpacing(lineSpacing: CGFloat = 0.0, lineHeightMultiple: CGFloat = 0.0) {
    padding = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) // CHANGED

    guard let labelText = self.text else { return }
    
    let paragraphStyle = NSMutableParagraphStyle()
    
    paragraphStyle.lineSpacing = lineSpacing
    paragraphStyle.lineHeightMultiple = lineHeightMultiple
    let attributedString: NSMutableAttributedString
    if let labelattributedText = self.attributedText {
        attributedString = NSMutableAttributedString(attributedString: labelattributedText)
    } else {
        attributedString = NSMutableAttributedString(string: labelText)
    }
    
    // (Swift 4.2 and above) Line spacing attribute
    attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range:NSMakeRange(0, attributedString.length))
    
    
    
    self.attributedText = attributedString
    if self.calculateMaxLines() == 1 { // CHANGED
        padding = UIEdgeInsets(top: lineSpacing, left: 0, bottom: lineSpacing, right: 0)

    }
    
    
}
  •  Tags:  
  • Related