sourcecode

스위프트에서 UILabel의 선 간격을 늘리는 방법

codebag 2023. 10. 10. 20:18
반응형

스위프트에서 UILabel의 선 간격을 늘리는 방법

텍스트 줄이 적은 라벨이 있는데 줄 사이 간격을 늘리고 싶습니다.다른 사람들이 묻는 비슷한 질문들이 있지만 해결책이 내 문제를 해결해 주지는 못합니다.또한 제 라벨에는 단락이 포함될 수도 있고 포함되지 않을 수도 있습니다.처음입니다.Swift. 스토리보드를 이용한 해결책이 있습니까?또는 을 통해서만NSAttributedString가능할까요?

줄 간격을 프로그램적으로 추가UILabel다음 토막글을 사용합니다.

스위프트 초기 버전

let attributedString = NSMutableAttributedString(string: "Your text")

// *** Create instance of `NSMutableParagraphStyle`
let paragraphStyle = NSMutableParagraphStyle()

// *** set LineSpacing property in points ***
paragraphStyle.lineSpacing = 2 // Whatever line spacing you want in points

// *** Apply attribute to string ***
attributedString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))

// *** Set Attributed String to your label ***
label.attributedText = attributedString

스위프트 4.0

let attributedString = NSMutableAttributedString(string: "Your text")

// *** Create instance of `NSMutableParagraphStyle`
let paragraphStyle = NSMutableParagraphStyle()

// *** set LineSpacing property in points ***
paragraphStyle.lineSpacing = 2 // Whatever line spacing you want in points

// *** Apply attribute to string ***
attributedString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))

// *** Set Attributed String to your label ***
label.attributedText = attributedString

스위프트 4.2

let attributedString = NSMutableAttributedString(string: "Your text")

// *** Create instance of `NSMutableParagraphStyle`
let paragraphStyle = NSMutableParagraphStyle()

// *** set LineSpacing property in points ***
paragraphStyle.lineSpacing = 2 // Whatever line spacing you want in points

// *** Apply attribute to string ***
attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))

// *** Set Attributed String to your label ***
label.attributedText = attributedString

인터페이스 빌더에서:

enter image description here

프로그래밍 방식:

스위프트 4 & 4.2

레이블 확장 사용

extension UILabel {

    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))


        // (Swift 4.1 and 4.0) Line spacing attribute
        attributedString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))

        self.attributedText = attributedString
    }
}

이제 내선번호 호출 기능

let label = UILabel()
let stringValue = "Set\nUILabel\nline\nspacing"

// Pass value for any one argument - lineSpacing or lineHeightMultiple
label.setLineSpacing(lineSpacing: 2.0) .  // try values 1.0 to 5.0

// or try lineHeightMultiple
//label.setLineSpacing(lineHeightMultiple = 2.0) // try values 0.5 to 2.0

또는 label instance를 사용(이 코드를 복사하여 실행하면 결과를 볼 수 있음)

let label = UILabel()
let stringValue = "Set\nUILabel\nline\nspacing"
let attrString = NSMutableAttributedString(string: stringValue)
var style = NSMutableParagraphStyle()
style.lineSpacing = 24 // change line spacing between paragraph like 36 or 48
style.minimumLineHeight = 20 // change line spacing between each line like 30 or 40

// Line spacing attribute
attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value: style, range: NSRange(location: 0, length: stringValue.characters.count))

// Character spacing attribute
attrString.addAttribute(NSAttributedStringKey.kern, value: 2, range: NSMakeRange(0, attrString.length))

label.attributedText = attrString

스위프트 3

let label = UILabel()
let stringValue = "Set\nUILabel\nline\nspacing"
let attrString = NSMutableAttributedString(string: stringValue)
var style = NSMutableParagraphStyle()
style.lineSpacing = 24 // change line spacing between paragraph like 36 or 48
style.minimumLineHeight = 20 // change line spacing between each line like 30 or 40
attrString.addAttribute(NSParagraphStyleAttributeName, value: style, range: NSRange(location: 0, length: stringValue.characters.count))
label.attributedText = attrString

라인 간격 조절이 가능합니다.storyboard.

enter image description here

같은 질문.

Swift 5.0에 대한 최근 솔루션

private extension UILabel {

    // MARK: - spacingValue is spacing that you need
    func addInterlineSpacing(spacingValue: CGFloat = 2) {

        // MARK: - Check if there's any text
        guard let textString = text else { return }

        // MARK: - Create "NSMutableAttributedString" with your text
        let attributedString = NSMutableAttributedString(string: textString)

        // MARK: - Create instance of "NSMutableParagraphStyle"
        let paragraphStyle = NSMutableParagraphStyle()

        // MARK: - Actually adding spacing we need to ParagraphStyle
        paragraphStyle.lineSpacing = spacingValue

        // MARK: - Adding ParagraphStyle to your attributed String
        attributedString.addAttribute(
            .paragraphStyle,
            value: paragraphStyle,
            range: NSRange(location: 0, length: attributedString.length
        ))

        // MARK: - Assign string that you've modified to current attributed Text
        attributedText = attributedString
    }

}

용도:

let yourLabel = UILabel()
let yourText = "Hello \n world \n !"
yourLabel.text = yourText
yourLabel.addInterlineSpacing(spacingValue: 1.5)

스위프트 4와 스위프트 5

extension NSAttributedString {
    func withLineSpacing(_ spacing: CGFloat) -> NSAttributedString {
        let attributedString = NSMutableAttributedString(attributedString: self)
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineBreakMode = .byTruncatingTail
        paragraphStyle.lineSpacing = spacing
        attributedString.addAttribute(.paragraphStyle,
                                      value: paragraphStyle,
                                      range: NSRange(location: 0, length: string.count))
        return NSAttributedString(attributedString: attributedString)
    }
}

사용방법

    let example = NSAttributedString(string: "This is Line 1 \nLine 2 \nLine 3 ").withLineSpacing(15)
    testLabel.attributedText = example

Example

이 재사용 가능한 확장자를 사용할 수 있습니다.

extension String {

func lineSpaced(_ spacing: CGFloat) -> NSAttributedString {
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.lineSpacing = spacing
    let attributedString = NSAttributedString(string: self, attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle])
    return attributedString
}
}

스위프트 4를 위해 업데이트 된 디펜의 답변

let attr = NSMutableAttributedString(string: today)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 2
attr.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, attr.length))
label.attributedText = attr;
extension UILabel {
    var spacing: CGFloat {
        get {return 0}
        set {
            let textAlignment = self.textAlignment
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.lineSpacing = newValue
            let attributedString = NSAttributedString(string: self.text ?? "", attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle])
            self.attributedText = attributedString
            self.textAlignment = textAlignment
        }
    }
}

let label = UILabel()
label.text = "test"
label.spacing = 10
//Swift 4:
    func set(text:String,
                         inLabel:UILabel,
                         withLineSpacing:CGFloat,
                         alignment:NSTextAlignment){
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.lineSpacing = withLineSpacing
            let attrString = NSMutableAttributedString(string: text)
            attrString.addAttribute(NSAttributedStringKey.paragraphStyle,
                                    value:paragraphStyle,
                                    range:NSMakeRange(0, attrString.length))
            inLabel.attributedText = attrString
            inLabel.textAlignment = alignment
          }

레이블 스타일 작성

struct LabelStyle {
    
        let font: UIFont
        let fontMetrics: UIFontMetrics?
        let lineHeight: CGFloat?
        let tracking: CGFloat
        
        init(font: UIFont, fontMetrics: UIFontMetrics? = nil, lineHeight: CGFloat? = nil, tracking: CGFloat = 0) {
            self.font = font
            self.fontMetrics = fontMetrics
            self.lineHeight = lineHeight
            self.tracking = tracking
        }
        
        func attributes(for alignment: NSTextAlignment, lineBreakMode: NSLineBreakMode) -> [NSAttributedString.Key: Any] {
            
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.alignment = alignment
            paragraphStyle.lineBreakMode = lineBreakMode
            
            var baselineOffset: CGFloat = .zero
            
            if let lineHeight = lineHeight {
                let lineHeightMultiple = lineHeight / font.lineHeight
                paragraphStyle.lineHeightMultiple = lineHeightMultiple
                
                baselineOffset = 1 / lineHeightMultiple
                
                let scaledLineHeight: CGFloat = fontMetrics?.scaledValue(for: lineHeight) ?? lineHeight
                paragraphStyle.minimumLineHeight = scaledLineHeight
                paragraphStyle.maximumLineHeight = scaledLineHeight
            }
            
            return [
                NSAttributedString.Key.paragraphStyle: paragraphStyle,
                NSAttributedString.Key.kern: tracking,
                NSAttributedString.Key.baselineOffset: baselineOffset,
                NSAttributedString.Key.font: font
            ]
        }
    }

사용자 지정 레이블 클래스를 만들고 스타일을 사용합니다.

public class Label: UILabel {
  
  var style: LabelStyle? { nil }
  
  public override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)
    
    if previousTraitCollection?.preferredContentSizeCategory != traitCollection.preferredContentSizeCategory {
      updateText()
    }
  }
  
  convenience init(text: String?, textColor: UIColor) {
    self.init()
    self.text = text
    self.textColor = textColor
  }
  
  override init(frame: CGRect) {
    super.init(frame: frame)
    commonInit()
  }
  
  required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    commonInit()
    updateText()
  }
  
  private func commonInit() {
    font = style?.font
    adjustsFontForContentSizeCategory = true
  }
  
  private func updateText() {
    text = super.text
  }
  
  public override var text: String? {
    get {
      guard style?.attributes != nil else {
        return super.text
      }
      
      return attributedText?.string
    }
    set {
      guard let style = style else {
        super.text = newValue
        return
      }
      
      guard let newText = newValue else {
        attributedText = nil
        super.text = nil
        return
      }
      
      let attributes = style.attributes(for: textAlignment, lineBreakMode: lineBreakMode)
      attributedText = NSAttributedString(string: newText, attributes: attributes)
    }
  }
}

콘크리트 레이블 작성

public final class TitleLabel {

    override var style: LabelStyle? {
        LabelStyle(
            font: UIFont.Title(),
            lineHeight: 26.21,
            tracking: 0.14
        )
    }
}

사용합니다.

@IBOutlet weak var titleLabel: TitleLabel!

속성 문자열 및 문단 스타일을 사용할 뿐만 아니라, 작은 조정을 위해 글꼴 설명자도 편리하게 사용할 수 있습니다.

예를 들어 다음과 같습니다.

let font: UIFont = .init(
    descriptor: UIFontDescriptor
        .preferredFontDescriptor(withTextStyle: .body)
        .withSymbolicTraits(.traitLooseLeading)!,
    size: 0
)

이렇게 하면 느슨하게 이어지는 글꼴이 생성되어 기본 시스템 글꼴보다 선 높이(2점 추가)가 약간 더 큰 텍스트가 생성됩니다.traitTightLeading반대 효과에도 사용할 수 있습니다(글꼴의 선두를 2포인트 줄여줍니다).

저는 여기 https://bootstragram.com/blog/line-height-with-uikit/ 접근법을 비교하는 블로그 게시물을 작성했습니다.

이 솔루션은 swift 5에서 작동했습니다. 이는 https://stackoverflow.com/a/62116213/13171606 의 답변과 관련된 내용입니다.

NSMutableAttributedString에 대해 몇 가지 변경을 했고 전체 예시를 포함했습니다. 모두에게 도움이 될 것 같습니다.

참고: 오류가 발견되면 색상 및 글꼴 스타일을 조정하십시오.

내선번호

extension NSAttributedString {
    func withLineSpacing(_ spacing: CGFloat) -> NSMutableAttributedString {
            let attributedString = NSMutableAttributedString(attributedString: self)
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.lineBreakMode = .byTruncatingTail
            paragraphStyle.lineSpacing = spacing
            attributedString.addAttribute(.paragraphStyle,
                                  value: paragraphStyle,
                                  range: NSRange(location: 0, length: string.count))
            return NSMutableAttributedString(attributedString: attributedString)
    }
}

구현 예시

let myAttributedText = NSMutableAttributedString(string: "Please enter the required details to change your AAAAAAAAA AAAAA AAAAA. Maximum AAAAA can be AAA AA AAA AA.\n\nNote: If you do not have a AAAAA AAAA then please AAAAAAA us at 111-111-111 or send us an email AAAA AAAA AAA AAAAAAAAAA AAAAA address at xxxxxxxxxxxxxxxxxxxxxxxxxxxx.", attributes: [
        .font: UIFont.systemFont(ofSize: 14),
        .foregroundColor: UIColor.gray,
        .kern: 0.0]).withLineSpacing(8)
    myAttributedText.addAttributes([
        .font: UIFont.systemFont(ofSize: 14),
        .foregroundColor: UIColor.blue],
                                   range: NSRange(location: 174, length: 11))
    myAttributedText.addAttributes([
        .font: UIFont.systemFont(ofSize: 14),
        .foregroundColor: UIColor.blue],
                                   range: NSRange(location: 248, length: 28))

UILable

let myLabel: UILabel = {
   let label = UILabel()
   label.textAlignment = .left
   label.numberOfLines = 0
   label.attributedText = myAttributedText //Here is your Attributed String
   return label
}() 
@discardableResult
func lineHeight(_ lineHeightMultiple: CGFloat) -> Self {
    guard let labelText = text else { return self}
    
    let fontHeight = font.lineHeight
    
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.lineSpacing = fontHeight * (lineHeightMultiple - 1)
    
    let attributedString = NSMutableAttributedString(string: labelText)
    attributedString.addAttribute(.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))
    
    attributedText = attributedString
    
    return self
}

언급URL : https://stackoverflow.com/questions/39158604/how-to-increase-line-spacing-in-uilabel-in-swift

반응형