ios - 화면 - swift4 layoutsubviews




setNeedsLayout 대 setNeedsUpdateConstraints 및 layoutIfNeeded 및 updateConstraintsIfNeeded가 필요합니다. (2)

자동 레이아웃 체인은 기본적으로 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 대신 -setNeedsLayout 사용 -setNeedsUpdateConstraints 모든 것이 예상대로 작동하지만, -layoutIfNeeded 하여 -updateConstraintsIfNeeded 변경하면 애니메이션이 실행되지 않는다는 것을 -updateConstraintsIfNeeded 습니다.
나는 내 자신의 결론을 내 렸습니다.

  • -updateConstraintsIfNeeded 는 제약 조건을 업데이트 -updateConstraintsIfNeeded 레이아웃을 프로세스에 강제 적용하지 않으므로 원본 프레임은 여전히 ​​보존됩니다.
  • -setNeedsLayout-updateContraints 메소드를 호출합니다.

그래서 다른 하나 대신에 하나를 사용하면 괜찮습니까? 그리고 레이아웃 방법에 관해서는 제약 조건이나 부모 뷰에서 변경된 뷰에서 호출해야합니까?


결론은 옳습니다. 기본 구성표는 다음과 같습니다.

  • setNeedsUpdateConstraintsupdateConstraintsIfNeeded 대한 향후 호출이 updateConstraintsIfNeeded 호출하도록합니다.
  • setNeedsLayout 는 앞으로 layoutIfNeeded 호출하여 layoutSubviews 호출하도록합니다.

layoutSubviews 가 호출되면 updateConstraintsIfNeeded 도 호출되기 때문에 수동으로 호출하는 것은 거의 필요하지 않습니다. 사실 레이아웃을 디버깅 할 때를 제외하고는 절대로 호출하지 않았습니다.

setNeedsUpdateConstraints 사용하여 제약 조건을 업데이트하는 것은 매우 드뭅니다. objc.io-a는 autolayouts에 대해 읽어야합니다 .

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

또한 필자의 경험에 비추어 볼 때 제약 조건을 무효화 할 필요가 없었고 새로운 제약 조건이 새로운 레이아웃을 요구하기 때문에 코드의 다음 줄에 setNeedsLayout 을 설정하지 않았습니다.

엄지 손가락의 규칙은 다음과 같습니다.

  • 제약 조건을 직접 조작 한 경우에는 setNeedsLayout 호출하십시오.
  • 재정의 된 updateConstraints 메소드 (제약 조건을 변경하는 권장 방법, btw)에서 제약 조건을 변경하는 일부 조건 (오프셋 또는 매끄럽게)을 변경 한 경우 setNeedsUpdateConstraints 호출하고 그 이후에는 대부분 setNeedsUpdateConstraints 호출합니다.
  • 위의 액션 중 하나라도 필요하다면 (예 : 레이아웃 통과 후 새 프레임 높이를 배울 필요가있는 경우) layoutIfNeeded 와 함께 추가하십시오.

또한 애니메이션 코드에서 setNeedsUpdateConstraints 는 불필요하다고 생각합니다. 제약 조건은 애니메이션보다 먼저 수동으로 업데이트되기 때문에 애니메이션은 이전과 새로운 애니메이션의 차이점을 기반으로 뷰를 다시 레이아웃하기 때문입니다.


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

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

  1. 나는 -setNeedsLayout 대신 -setNeedsLayout 사용 -setNeedsUpdateConstraints 모든 것이 예상대로 작동하지만, -layoutIfNeeded 하여 -updateConstraintsIfNeeded 변경하면 애니메이션이 실행되지 않는다는 것을 -updateConstraintsIfNeeded 습니다.

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

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

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

updateConstraints 를 호출하려면 다음을 수행해야합니다.

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




nslayoutconstraint