ProgramingTip

intrinsicContentSize 및 sizeThatFits의 적절한 사용 : 자동 레이아웃이있는 UIView 하위 클래스에서

bestdevel 2020. 12. 5. 10:22
반응형

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하는 재정의와 함께 내 하위 클래스의 텍스트를 편집 할 때 마다 호출 할 수 있다고하는 것이 적절하다고 생각하지 않습니다.intrinsicContentSizesizeThatFits:

나는 오버라이드 (override)에 대해 생각 needsUpdateConstraints하고 updateConstraints, 그러나 아직도 내 폭의 폭과 높이를 추정하고, XIB에서 마스크를 자동 크기로 번역하므로 뷰 의미가 있습니다.

지금까지 여기서 여기서 보여준 것을 정확히 만들고 완전 자동 레이아웃을 지원하는 가장 깨끗하고 올바른 방법이 무엇이라고 생각하십니까?


intrinsicContentSize를 정의 할 필요가 없다고 생각합니다.

다음과 같은 두 가지 이유가 있습니다.

  1. 자동 레이아웃 문서에서 설명 할 때 할 때 intrinsicContentSize버튼이나 라벨과 같은 '리프 뷰'와 관련이있는 콘텐츠를 기준으로 크기를 계산할 수 있습니다. 아이디어는 다른 뷰로 구성되지 않기 때문에 분기가 아닌 뷰 계층 구조 트리의 리프라는 것입니다.

  2. IntrinsicContentSize는 실제로 자동 레이아웃의 "기본"개념이 아닙니다. 기본 개념은 제약 조건과 제약 조건으로 묶인 속성입니다. intrinsicContentSize, 콘텐츠 포옹 우선 순위 및 압축 저항 우선 순위는 실제로 크기와 관련된 내부 제약을 생성하는 데 사용되는 편리함입니다. 최종 크기는 일반적인 방식으로 모든 제약 조건과 상호 작용하는 제약 조건의 결과입니다.

그래서 뭐? 따라서 "사용자 지정보기"가 실제로 몇 가지 다른보기의 어셈블리 인 경우 intrinsicContentSize를 정의 할 필요가 없습니다. 원하는 레이아웃을 만드는 제약 조건을 정의하기 만하면 이러한 제약 조건이 원하는 크기를 생성 할 수도 있습니다.

설명하는 특별한 경우에는 레이블에서 superview로> = 0 bottom space 제약 조건을 설정하고 이미지에서 superview로 다른 제약 조건을 설정 한 다음 뷰에 대해 높이 0 낮은 우선 순위 제약 조건을 전부의. 낮은 우선 순위 제약 조건은 어셈블리 축소를 시도하고 다른 제약 조건은 어셈블리 축소를 중지하여 하위 뷰를 클립합니다.

intrinsicContentSize를 명시 적으로 정의하지 않은 경우 이러한 제약으로 인한 크기를 어떻게 볼 수 있습니까? 한 가지 방법은 레이아웃을 강제 적용한 다음 결과를 관찰하는 것입니다.

또 다른 방법은 사용하는 것입니다 systemLayoutSizeFittingSize:(iOS8에서는 거의 예고되지 않은 systemLayoutSizeFittingSize:withHorizontalFittingPriority:verticalFittingPriority:). 이것은 sizeThatFits:보다 더 가까운 사촌 입니다 intrinsicContentSize. 시스템은 본질적인 콘텐츠 크기 제약 및 기타 모든 제약을 포함하여 포함 된 모든 제약을 고려하여 뷰의 적절한 크기를 계산하는 데 사용합니다.

안타깝게도 여러 줄 레이블 preferredMaxLayoutWidth이있는 경우 좋은 결과를 얻으려면 구성해야 할 수도 있지만 이는 또 다른 이야기입니다.

참고 URL : https://stackoverflow.com/questions/24127032/proper-usage-of-intrinsiccontentsize-and-sizethatfits-on-uiview-subclass-with-a

반응형