UILabel
완벽한 솔루션 패딩 . 2020 년에 업데이트되었습니다.
수행해야 할 세 가지 가 있음이 밝혀 졌습니다.
1. 새로운 작은 크기로 textRect # forBounds 를 호출해야 합니다.
2. 새로운 작은 크기로 drawText를 재정의해야합니다.
3. 동적 크기의 셀인 경우 intrinsicContentSize를 조정해야합니다.
아래의 일반적인 예에서 텍스트 단위는 테이블보기, 스택보기 또는 이와 유사한 구성으로 고정 너비 를 제공합니다 . 이 예에서는 60,20,20,24의 패딩을 원합니다.
따라서 "존재하는"intrinsicContentSize를 가져와 실제로 height에 80을 추가합니다 .
반복하려면 ...
엔진에 의해 "지금까지"계산 된 높이를 문자 그대로 "얻고" 그 값을 변경 해야합니다.
그 과정이 혼란 스럽지만 그것이 작동하는 방식입니다. 나에게있어, 애플은 "예비 높이 계산"과 같은 이름의 전화를 공개해야한다.
두 번째로 textRect # forBounds 호출 을 새로운 작은 크기로 사용해야합니다 .
따라서 textRect # forBounds에서 먼저 크기를 작게 한 다음 super 를 호출합니다.
경보! 당신은 해야한다 슈퍼 호출 후 ,하지 전에!
이 페이지에 대한 모든 시도와 토론을주의 깊게 조사하면 정확한 문제입니다. 일부 솔루션은 "거의 작동하는 것 같다"고 생각하지만 특정 상황에서는 작동하지 않을 것이라고 누군가가보고합니다. 이것이 바로 정확한 이유입니다. 혼동스럽게도 이전이 아니라 나중에 "슈퍼 콜"을해야합니다.
따라서 super를 "잘못된 순서로"호출하면 일반적으로 작동 하지만 특정 텍스트 길이에는 적용되지 않습니다 .
다음은 "부적절하게 슈퍼를 먼저 수행"하는 정확한 시각적 예입니다.
textRect # forBounds의 "super first"패턴으로 수행 되었기 때문에 60,20,20,24 여백이 올바른지 확인하십시오. 그러나 크기 계산은 실제로 잘못되었습니다.
결정된:
이제 textRect # forBounds 엔진 만이 계산을 올바르게 수행하는 방법을 알고 있습니다 .
드디어!
이 예제에서 UILabel은 너비가 고정 된 일반적인 상황에서 사용됩니다. 따라서 intrinsicContentSize에서는 원하는 전체 높이를 "추가"해야합니다. (너비에 어떤 식 으로든 "추가"할 필요는 없습니다. 고정되어 있으므로 의미가 없습니다.)
그런 다음 textRect # forBounds에서 자동 레이아웃으로 "지금까지 제안 된"범위를 확보하고 여백 을 뺀 다음 textRect # forBounds 엔진을 다시 호출하십시오. 즉, super로 말하면 결과가 나타납니다.
마지막으로 간단하게 drawText에서 동일한 작은 상자에 그릴 수 있습니다.
휴!
let UIEI = UIEdgeInsets(top: 60, left: 20, bottom: 20, right: 24) // as desired
override var intrinsicContentSize:CGSize {
numberOfLines = 0 // don't forget!
var s = super.intrinsicContentSize
s.height = s.height + UIEI.top + UIEI.bottom
s.width = s.width + UIEI.left + UIEI.right
return s
}
override func drawText(in rect:CGRect) {
let r = rect.inset(by: UIEI)
super.drawText(in: r)
}
override func textRect(forBounds bounds:CGRect,
limitedToNumberOfLines n:Int) -> CGRect {
let b = bounds
let tr = b.inset(by: UIEI)
let ctr = super.textRect(forBounds: tr, limitedToNumberOfLines: 0)
// that line of code MUST be LAST in this function, NOT first
return ctr
}
다시 한번. "거의"올바른이 QA 및 기타 QA에 대한 답변은 위의 첫 번째 이미지 ( "슈퍼가 잘못된 위치에 있습니다")에서 문제를 겪 습니다 . intrinsicContentSize에서 크기를 크게 한 다음 textRect # forBounds 에서 먼저 첫 번째 제안 범위를 축소 한 다음 super 를 호출 해야합니다 .
요약 : textRect # forBounds에서 " 최근 호출 "
그것이 비밀입니다.
무효화, sizeThatFits, needsLayout 또는 기타 강제 호출을 추가로 호출 할 필요가 없으며 추가로 호출 할 필요가 없습니다. 정상적인 자동 레이아웃 인출 사이클에서 올바른 솔루션이 올바르게 작동해야합니다.
팁:
모노 스페이스 글꼴로 작업하는 경우 다음 팁을 참조하십시오 . https://stackoverflow.com/a/59813420/294884