관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 문자열에 들여쓰기 적용하는 방법 (indent, bullet, NSMutableParagraphStyle, headIndent, NSAttributedString, 불릿 텍스트) 본문

iOS 응용 (swift)

[iOS - swift] 문자열에 들여쓰기 적용하는 방법 (indent, bullet, NSMutableParagraphStyle, headIndent, NSAttributedString, 불릿 텍스트)

jake-kim 2024. 8. 2. 01:48

문자열 bullet 기준 들여쓰기 UI

  • bullet기준으로 텍스트들이 들여쓰기 되어있는 UI

폰트가 큰 경우에도 들여쓰기 기준 동일)

let text = """
• 첫 번째 텍스트 이빈다. 이것은 bullet 테스트, 과연 긴 텍스트가 있을 때 indent가 어떻게 적용될 것인가 테스트 해봅니다. iOS 앱 블로그 알아가기 jake에서 살펴봅니다.
• 두 번째 텍스트 입니다.
"""

문자열 bullet 기준 들여쓰기 구현 아이디어

  • 뷰와 UILabel 준비
import UIKit

class ViewController: UIViewController {
    private let label = {
        let l = UILabel()
        l.font = .systemFont(ofSize: 30)
        l.numberOfLines = 0
        l.textColor = .black
        l.translatesAutoresizingMaskIntoConstraints = false
        return l
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.addSubview(label)
        NSLayoutConstraint.activate([
            label.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            label.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            label.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)
        ])
        
        addText()
    }
    
    private func addText() {
        // TODO ...
    }
}
  • indent 구현 원리
    • UILabel에는 attributedText 프로퍼티가 있으므로 이 프로퍼티에 indent 스타일을 적용할 attributedText를 주입하여 구현
    • NSAttributedString에는 .paragraphStyle 속성이 있는데, paragraphStyle에는 NSMutableParagraphStyle 인스턴스
  • NSMutableParagraphStyle인스턴스에는 여러가지 속성이 있는데, 그 중에서 headIndent 속성을 사용

문자열 bullet 기준 들여쓰기 구현하기

  • text를 준비하고, 여기에 사용되는 bullet문자열을 기준으로 width를 구해내고 width를 구해내기
    • (아래 bulletTextIndent 프로퍼티는 따로 extension으로 빼도 무방)
    private func addText() {
        let text = """
        • 첫 번째 텍스트 이빈다. 이것은 bullet 테스트, 과연 긴 텍스트가 있을 때 indent가 어떻게 적용될 것인가 테스트 해봅니다. iOS 앱 블로그 알아가기 jake에서 살펴봅니다.
        • 두 번째 텍스트 입니다.
        """
        
        let bulletTextIndent = {
            let l = UILabel()
            l.text = "•"
            l.font = self.label.font
            return l.sizeThatFits(.zero).width * 5/3 // 5/3은 "•" 인덴트 길이를 보며 임의로 맞춘 값
        }()
  • paragraphStyle에 indent 값을 어싸인하고, paragraphStyle를 attributedText에 사용
  • attributedText를 label에 넣어주면 완료
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.headIndent = bulletTextIndent

        // NSAttributedString을 사용하여 스타일 적용
        let attributedText = NSAttributedString(string: text, attributes: [
            .paragraphStyle: paragraphStyle
        ])

        // UILabel에 설정된 NSAttributedString 적용
        label.attributedText = attributedText
        label.text = text

* 전체 코드: https://github.com/JK0369/ExBulletText

* 참고

- https://developer.apple.com/documentation/uikit/nsmutableparagraphstyle

Comments