[ios] setNeedsLayout vs. setNeedsUpdateConstraints 및 layoutIfNeeded vs updateConstraintsIfNeeded

자동 레이아웃 체인은 기본적으로 3 가지 프로세스로 구성됩니다.

  1. 구속 조건 업데이트
  2. 레이아웃 뷰 (여기서 프레임 계산을 수행하는 위치)
  3. 디스플레이

무엇 완전히 나에게 분명하지 않다 것은 사이의 내부 차이 -setNeedsLayout-setNeedsUpdateConstraints. Apple Docs에서 :

setNeedsLayout

뷰의 서브 뷰 레이아웃을 조정하려면 응용 프로그램의 메인 스레드에서이 메소드를 호출하십시오. 이 메소드는 요청을 기록하고 즉시 리턴합니다. 이 방법은 즉시 업데이트를 강제하지 않지만 대신 다음 업데이트주기를 기다리기 때문에 여러 뷰의 레이아웃을 무효화하여 해당 뷰를 업데이트 할 수 있습니다. 이 동작을 통해 모든 레이아웃 업데이트를 한 번의 업데이트 주기로 통합 할 수 있으며 이는 일반적으로 성능이 향상됩니다.

setNeedsUpdateConstraints

사용자 지정 뷰의 속성이 제약 조건에 영향을주는 방식으로 변경되면이 메서드를 호출하여 나중에 제약 조건을 업데이트해야 함을 나타낼 수 있습니다. 그런 다음 시스템은 일반 레이아웃 패스의 일부로 updateConstraints를 호출합니다. 구속 조건을 요구하기 바로 전에 한 번에 모두 구속 조건을 업데이트하면 배치 단계 사이에서 뷰를 여러 번 변경할 때 구속 조건을 불필요하게 다시 계산할 필요가 없습니다.

제약 조건을 수정 한 후 뷰에 애니메이션을 적용하고 변경 사항에 애니메이션을 적용하려면 일반적으로 예를 들어 호출합니다.

[UIView animateWithDuration:1.0f delay:0.0f usingSpringWithDamping:0.5f initialSpringVelocity:1 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        [self.modifConstrView setNeedsUpdateConstraints];
        [self.modifConstrView layoutIfNeeded];
    } completion:NULL];

내가 사용하는 경우 사실을 발견했습니다 -setNeedsLayout대신 -setNeedsUpdateConstraints모든 작업이 예상대로,하지만 난 변경하는 경우 -layoutIfNeeded-updateConstraintsIfNeeded, 애니메이션은 일어나지 않을 것입니다.
나는 내 자신의 결론을 만들려고 노력했다.

  • -updateConstraintsIfNeeded 구속 조건 만 업데이트하지만 레이아웃을 강제로 프로세스로 가져 오지 않으므로 원본 프레임이 계속 유지됩니다.
  • -setNeedsLayout-updateContraints메소드 도 호출

그렇다면 언제 다른 것을 사용하는 것이 좋을까요? 레이아웃 방법에 대해 제약 조건이나 상위 뷰가 변경된 뷰에서 호출해야합니까?



답변

당신의 결론은 옳습니다. 기본 체계는 다음과 같습니다.

  • setNeedsUpdateConstraints앞으로 전화를해야 updateConstraintsIfNeeded합니다 updateConstraints.
  • setNeedsLayout앞으로 전화를해야 layoutIfNeeded합니다 layoutSubviews.

경우 layoutSubviews라고, 또한 호출 updateConstraintsIfNeeded때문에 수동으로 거의 내 경험에 필요하지 않습니다 호출. 실제로 레이아웃을 디버깅 할 때를 제외하고는 호출하지 않았습니다.

자동 제약 조건을 사용하여 제약 조건을 업데이트하는 setNeedsUpdateConstraints것도 매우 드,니다. objc.io는 자동 레이아웃에 대해 읽어야합니다 .

나중에 변경되어 제약 조건 중 하나가 무효화되는 경우 제약 조건을 즉시 제거하고 setNeedsUpdateConstraints를 호출해야합니다. 실제로, 제약 조건 업데이트 패스를 트리거해야하는 유일한 경우입니다.

또한 내 경험상 제약 조건을 무효화 할 필요가 없었으며 setNeedsLayout코드의 다음 줄에서 설정하지 않아도 되었습니다. 새로운 제약 조건이 거의 새로운 레이아웃을 요구하기 때문입니다.

경험 법칙은 다음과 같습니다.

  • 제약 조건을 직접 조작 한 경우을 호출하십시오 setNeedsLayout.
  • 당신은 (오프셋 또는 떨어지게 같은) 일부 조건 변경 한 경우 재정의 된 제약 조건 변경 updateConstraints(BTW, 변경 제약에 권장되는 방법) 메소드를 호출 setNeedsUpdateConstraints하고, 대부분의 시간, setNeedsLayout그 이후를.
  • 예를 들어 레이아웃 패스 후 새로운 프레임 높이를 배워야 할 때와 같이 즉각적인 효과를 얻기 위해 위의 작업이 필요한 경우을 추가하십시오 layoutIfNeeded.

또한 애니메이션 코드 setNeedsUpdateConstraints에서 애니메이션 전에 수동으로 구속 조건이 업데이트되고 애니메이션이 이전과 새로운 차이점의 차이에 따라 뷰를 다시 레이아웃하기 때문에 필요하지 않다고 생각 합니다.


답변

coverback에 의한 대답은 꽤 정확합니다. 그러나 추가 세부 정보를 추가하고 싶습니다.

다음은 다른 동작을 설명하는 일반적인 UIView주기 다이어그램입니다.

UIView의 라이프 사이클

  1. 내가 사용하는 경우 사실을 발견했습니다 -setNeedsLayout대신 -setNeedsUpdateConstraints모든 작업이 예상대로,하지만 난 변경하는 경우 -layoutIfNeeded-updateConstraintsIfNeeded, 애니메이션은 일어나지 않을 것입니다.

updateConstraints일반적으로 아무것도하지 않습니다. layoutSubviews호출 될 때까지 적용되지 않는 제약 조건을 해결합니다 . 따라서 애니메이션에는에 대한 호출이 필요합니다 layoutSubviews.

  1. setNeedsLayout도 -updateContraints 메소드를 호출합니다.

필요하지 않습니다. 제약 조건이 수정되지 않은 경우 UIView는에 대한 호출을 건너 뜁니다 updateConstraints. setNeedsUpdateConstraint프로세스에서 제약 조건을 수정 하려면 명시 적으로 호출해야합니다 .

전화 updateConstraints하려면 다음을 수행해야합니다.

[view setNeedsUpdateConstraints];
[view setNeedsLayout];
[view layoutIfNeeded];


답변