programing

UIView의 세트 NeedsLayout, layoutIfNeeded 및 layoutSubviews 사이의 관계는 무엇입니까?

stoneblock 2023. 7. 8. 10:32

UIView의 세트 NeedsLayout, layoutIfNeeded 및 layoutSubviews 사이의 관계는 무엇입니까?

누가 사이의 관계에 대해 결정적인 설명을 해줄 수 있습니까?UIView's setNeedsLayout,layoutIfNeeded그리고.layoutSubviews방법? 를 모두 예제 .그리고 이 세 가지를 모두 사용할 수 있는 예제 구현입니다.감사해요.

내가 혼란스러운 것은 내가 내 사용자 정의 보기를 보낸다면setNeedsLayout 이 은 " 메지이메다드음호에출는것같다다습니음과은되시"."입니다.layoutSubviews 건너뛰기layoutIfNeeded서류상으로는 흐름이setNeedsLayout > 인원layoutIfNeeded> 원인이라고 할 수 있습니다.layoutSubviews다음 호에

저는 아직도 스스로 이 문제를 해결하려고 노력하고 있으니, 이것을 좀 회의적으로 받아들이고 오류가 포함되어 있다면 용서해 주십시오.

setNeedsLayout쉬운 방법입니다. UI 보기 어딘가에 레이아웃이 필요한 것으로 표시하는 플래그를 설정하면 됩니다.그것은 어쩔 수 없습니다.layoutSubviews다음에 다시 그리기가 발생하기 전에 보기에서 호출됩니다.대부분의 경우 이를 명시적으로 부를 필요가 없습니다.autoresizesSubviews뷰가 됩니다.기본값으로 설정된 경우 뷰 프레임을 변경하면 뷰가 하위 뷰를 레이아웃합니다.

layoutSubviews당신이 모든 흥미로운 것들을 하는 방법입니다.이와 맞먹습니다.drawRect레이아웃을 위해, 만약 당신이 원한다면.간단한 예는 다음과 같습니다.

-(void)layoutSubviews {
    // Child's frame is always equal to our bounds inset by 8px
    self.subview1.frame = CGRectInset(self.bounds, 8.0, 8.0);
    // It seems likely that this is incorrect:
    // [self.subview1 layoutSubviews];
    // ... and this is correct:
    [self.subview1 setNeedsLayout];
    // but I don't claim to know definitively.
}

AFAIKlayoutIfNeeded일반적으로 하위 클래스에서 재정의되지 않습니다.이 방법은 지금 당장 뷰를 배치하고 싶을 때 호출해야 하는 방법입니다.Apple의 구현은 다음과 같습니다.

-(void)layoutIfNeeded {
    if (self._needsLayout) {
        UIView *sv = self.superview;
        if (sv._needsLayout) {
            [sv layoutIfNeeded];
        } else {
            [self layoutSubviews];
        }
    }
}

당신은 전화할 것입니다.layoutIfNeeded(필요에 따라) 즉시 배치하도록 강제하는 관점에서.

경우에는 N8gray에 n8gray의 . 어떤 경우에는 전화를 해야 할 것입니다.setNeedsLayout에 뒤에layoutIfNeeded.

예를 들어, UIView를 확장하는 사용자 정의 보기를 작성했다고 가정해 보겠습니다. 이 보기에서는 하위 보기의 위치 지정이 복잡하고 마스크 또는 iOS6 AutoLayout을 자동으로 크기 조정할 수 없습니다.사용자 지정 위치 지정은 다음을 재정의하여 수행할 수 있습니다.layoutSubviews.

예를 들어 다음과 같은 사용자 정의 보기가 있다고 가정합니다.contentView과 재산edgeInsets내용 보기 주변의 여백을 설정할 수 있는 속성입니다. layoutSubviews다음과 같이 표시됩니다.

- (void) layoutSubviews {
    self.contentView.frame = CGRectMake(
        self.bounds.origin.x + self.edgeInsets.left,
        self.bounds.origin.y + self.edgeInsets.top,
        self.bounds.size.width - self.edgeInsets.left - self.edgeInsets.right,
        self.bounds.size.height - self.edgeInsets.top - self.edgeInsets.bottom); 
}

을 할 변경을 수 있기를 ,edgeInsets속성, 당신은 그것을 재정의해야 합니다.edgeInsets다음과 같이 세터를 설정하고 전화를 합니다.setNeedsLayout다음에layoutIfNeeded:

- (void) setEdgeInsets:(UIEdgeInsets)edgeInsets {
    _edgeInsets = edgeInsets;
    [self setNeedsLayout]; //Indicates that the view needs to be laid out 
                           //at next update or at next call of layoutIfNeeded, 
                           //whichever comes first 
    [self layoutIfNeeded]; //Calls layoutSubviews if flag is set
}

이렇게 하면 애니메이션 블록 내에서 edgeInsets 속성을 변경하면 contentView의 프레임 변경이 애니메이션으로 표시됩니다.

[UIView animateWithDuration:2 animations:^{
    customView.edgeInsets = UIEdgeInsetsMake(45, 17, 18, 34);
}];

setEdgeInsets 메서드에서 layoutIfNeeded에 호출을 추가하지 않으면 다음 업데이트 주기에 layoutSubviews가 호출되므로 애니메이션이 작동하지 않습니다. 이는 애니메이션 블록 외부에서 호출하는 것과 같습니다.

setEdgeInsets 메서드에서 layoutIfNeeded만 호출하는 경우 setNeedsLayout 플래그가 설정되지 않았기 때문에 아무 일도 일어나지 않습니다.

언급URL : https://stackoverflow.com/questions/2807137/what-is-the-relationship-between-uiviews-setneedslayout-layoutifneeded-and-lay