본문 바로가기
iOS/설명

[iOS] NSAttributedString.boundingRect

by Sky Titan 2022. 11. 26.
728x90
 

Confused by NSStringDrawingOptions item meaning

iOS7 and later, we can use - (void)drawWithRect:(CGRect)rect options:(NSStringDrawingOptions)options attributes:(NSDictionary *)attributes context:(NSStringDrawingContext *)context to calculate the

stackoverflow.com

 

 

IOS) 동적인 Collection Cell 크기 만들기 - (부정확)

안녕하세요 후르륵짭짭 입니다. 이번에는 문자열의 길이에 따라 Cell의 크기를 다르게 해주는 방법에 대해 알아 보도록 하겠습니다. 그런데 아직 확실한 내용이 아니기 때문에,,,, 쫌 많이 걸러

hururuek-chapchap.tistory.com

boundingRect(with:options:attributes:context:)

  • receiver인 attributed String의 bounding rect를 계산해서 반환해주는 함수
    • 해당 text를 표현하는데 필요한 크기(높이, 너비) 를 계산할 수 있다
  • multi-line text의 크기를 계산하려면, useLineFragmentOrigin을 options 파라미터에 적용해야한다.
    • 문자열이 rect에 다 담을 수 없다면 문자열의 간격을 조절해주는 옵션
    • 사실상 텍스트의 정확한 높이를 계산하기 위해서 꼭 필요한 옵션
  • 반환된 사이즈를 view에 적용할 때는, ceil 함수를 통해서 올림처리를 해주어야 한다.
    • 의외로 이걸 안해줘서 줄바꿈시 문제가 높이에 문제가 생기는 경우들이 종종 있음

 

Example

  • 중앙에 양 옆의 마진을 24로 둔 label에 적용될 string의 높이를 계산하는 예시
import UIKit

class ViewController: UIViewController {
   
    @IBOutlet weak var label: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let attributedString = NSAttributedString(string: "안녕하세요안녕하세요안녕하세요안녕하세요안녕하세요안녕하세요안녕하세요안녕하세요안녕하세요안녕하세요안녕하세요", attributes: [.font: UIFont.systemFont(ofSize: 19)])
        
        let width: CGFloat = UIScreen.main.bounds.width - 48
        let height = attributedString.boundingRect(with: CGSize(width: width, height: CGFloat.infinity), options: .usesLineFragmentOrigin, context: nil).height
        
        label.attributedText = attributedString
        label.sizeToFit()
        
        print("estimated height: \(height)")
        
        print("label height : \(label.frame.height)")
    }
}

 계산된 높이와 실제 label에 적용된 높이 사이엔 오차가 있다. 아마 UIView에 적용될 땐 어느정도 보정과정을 거치는 것 같고, 때문에 가이드에서 실제 view에 적용된 높이를 구하고 싶으면 ceil을 통해 올림 처리를 해야 잘리는 text가 없이 화면에 제대로 보이는 높이가 구해지는 것 같다.

728x90

댓글