intrinsicContentSize 및 sizeThatFits의 적절한 사용 : 자동 레이아웃이있는 UIView 하위 클래스에서
나는이 (어 · 든) 간단한 질문을합니다. 까다롭게 묻고 있습니다. UIView의 API를 잘못 사용하는 것에 대해 걱정하기 때문에 자동 레이아웃과 관련하여.
매우 간단하게 만들기 위해 이미지 아이콘과 여러 줄 레이블이있는 UIView 하위 클래스가 필요합니다. 가정 해 보겠습니다. 내가 원하는 동작은 내 뷰의 높이가 레이블의 높이에 따라 변경된 것입니다 (텍스트에 맞게), 또한 인터페이스 빌더를 사용하여 레이아웃하고 다음과 가능합니다.
이미지보기에 고정 너비와 높이를 제공하고 라벨에 고정 너비와 위치 (이미지보기에 최다)를 제공하는 몇 가지 제약 조건이 있습니다.
이제 레이블에 텍스트를 표시하면 뷰의 높이가 지정하게 설정되거나 xib에있는 것과 동일한 높이로 유지되기를 원합니다. 자동 레이아웃 이전에는 항상 다음과 같은 작업을 수행했을 것입니다.
CustoView 클래스 파일에서 하위 sizeThatFits:
다음과 같이 재정의 했을을 구석으로입니다.
- (CGSize) sizeThatFits:(CGSize)size{
//this stands for whichever method I would have used
//to calculate the height needed to display the text based on the font
CGSize labelSize = [self.titleLabel intrinsicContentSize];
//check if we're bigger than what's in ib, otherwise resize
CGFloat newHeight = (labelSize.height <= 21) ? 51: labelSize.height+20;
size.height = newHeight;
return size;
}
그리고 내가 다음과 같이 부르는 것보다 :
myView.titleLabel.text = @"a big text to display that should be more than a line";
[myView sizeToFit];
이제 제약 조건에서 생각하면 자동 레이아웃 시스템 intrinsicContentSize
이 뷰 트리 요소를 호출 하여하여 크기를 구현하고 계산을 수행한다는 것을 알고 있기 이전에 메소드 intrinsicContentSize
에서 반환하는 것과 동일한 것을 반환하고 하위에서 재정의해야 합니다. sizeThatFits:
에 호출 할 이전 때 sizeToFit
뷰의 크기가 적절하게 조정되었지만 이제는 XIB와 함께 자동 레이아웃을 사용하면 이런 일이 발생하지 않습니다 .
물론 똑같은 크기를 반환 sizeToFit
하는 재정의와 함께 내 하위 클래스의 텍스트를 편집 할 때 마다 호출 할 수 있다고하는 것이 적절하다고 생각하지 않습니다.intrinsicContentSize
sizeThatFits:
나는 오버라이드 (override)에 대해 생각 needsUpdateConstraints
하고 updateConstraints
, 그러나 아직도 내 폭의 폭과 높이를 추정하고, XIB에서 마스크를 자동 크기로 번역하므로 뷰 의미가 있습니다.
지금까지 여기서 여기서 보여준 것을 정확히 만들고 완전 자동 레이아웃을 지원하는 가장 깨끗하고 올바른 방법이 무엇이라고 생각하십니까?
intrinsicContentSize를 정의 할 필요가 없다고 생각합니다.
다음과 같은 두 가지 이유가 있습니다.
자동 레이아웃 문서에서 설명 할 때 할 때
intrinsicContentSize
버튼이나 라벨과 같은 '리프 뷰'와 관련이있는 콘텐츠를 기준으로 크기를 계산할 수 있습니다. 아이디어는 다른 뷰로 구성되지 않기 때문에 분기가 아닌 뷰 계층 구조 트리의 리프라는 것입니다.IntrinsicContentSize는 실제로 자동 레이아웃의 "기본"개념이 아닙니다. 기본 개념은 제약 조건과 제약 조건으로 묶인 속성입니다. intrinsicContentSize, 콘텐츠 포옹 우선 순위 및 압축 저항 우선 순위는 실제로 크기와 관련된 내부 제약을 생성하는 데 사용되는 편리함입니다. 최종 크기는 일반적인 방식으로 모든 제약 조건과 상호 작용하는 제약 조건의 결과입니다.
그래서 뭐? 따라서 "사용자 지정보기"가 실제로 몇 가지 다른보기의 어셈블리 인 경우 intrinsicContentSize를 정의 할 필요가 없습니다. 원하는 레이아웃을 만드는 제약 조건을 정의하기 만하면 이러한 제약 조건이 원하는 크기를 생성 할 수도 있습니다.
설명하는 특별한 경우에는 레이블에서 superview로> = 0 bottom space 제약 조건을 설정하고 이미지에서 superview로 다른 제약 조건을 설정 한 다음 뷰에 대해 높이 0 의 낮은 우선 순위 제약 조건을 전부의. 낮은 우선 순위 제약 조건은 어셈블리 축소를 시도하고 다른 제약 조건은 어셈블리 축소를 중지하여 하위 뷰를 클립합니다.
intrinsicContentSize를 명시 적으로 정의하지 않은 경우 이러한 제약으로 인한 크기를 어떻게 볼 수 있습니까? 한 가지 방법은 레이아웃을 강제 적용한 다음 결과를 관찰하는 것입니다.
또 다른 방법은 사용하는 것입니다 systemLayoutSizeFittingSize:
(iOS8에서는 거의 예고되지 않은 systemLayoutSizeFittingSize:withHorizontalFittingPriority:verticalFittingPriority:
). 이것은 sizeThatFits:
보다 더 가까운 사촌 입니다 intrinsicContentSize
. 시스템은 본질적인 콘텐츠 크기 제약 및 기타 모든 제약을 포함하여 포함 된 모든 제약을 고려하여 뷰의 적절한 크기를 계산하는 데 사용합니다.
안타깝게도 여러 줄 레이블 preferredMaxLayoutWidth
이있는 경우 좋은 결과를 얻으려면 구성해야 할 수도 있지만 이는 또 다른 이야기입니다.
'ProgramingTip' 카테고리의 다른 글
Google 인덱싱 내 Github 저장소를 중지하는 방법 (0) | 2020.12.05 |
---|---|
Google server putty connect '연결 끈 : 지원되는 인증 방법이 없습니다 (전송 된 서버 : 공개 키). (0) | 2020.12.05 |
JavaScript를 자동화 된 단위 테스트 (0) | 2020.12.05 |
Scala에서 단일 아포스트로피는 무엇을 의미합니까? (0) | 2020.12.05 |
iOS : 오픈 소스 VoIP / SIP Objective-C 코드 (0) | 2020.12.05 |