IT

레이아웃 제약은 언제 활성화 / 비활성화 할 수 있습니까?

lottoking 2020. 9. 4. 07:43
반응형

레이아웃 제약은 언제 활성화 / 비활성화 할 수 있습니까?


IB에 여러 제약 조건 세트를 설정하고 일부 상태에 따라 프로그래밍 방식으로 전환하고 싶습니다. 거기의 constraintsAIB에서 설치로 설치되어 모두 출구 컬렉션, 그리고 constraintsB모든 출구 수집은 IB에서 제거됩니다.

다음과 같이 프로그래밍 방식으로 두 세트간에 전환 할 수 있습니다.

NSLayoutConstraint.deactivateConstraints(constraintsA)
NSLayoutConstraint.activateConstraints(constraintsB)

근데 ... 언제할지 할지 모르겠어요 . 에서 한 번 할 수있는 것 같지만 viewDidLoad작동하지 않습니다. 나는 전화 해봤 view.updateConstraints()view.layoutSubviews()제약 조건을 설정 한 후,하지만 소용.

viewDidLayoutSubviews모든 제약 조건을 설정하면 예상 대로 작동하게 됩니다. 두 가지를 알고 싶은 것 같아요 ...

  1. 이 동작이 발생하는 이유는 무엇입니까?
  2. viewDidLoad에서 제약 조건을 활성화 / 할 수 있습니까?

활성화 및 비활성화에서 NSLayoutConstraints했는데 viewDidLoad아무런 문제가 없습니다. 그래서 작동합니다. 앱과 내 앱 사이에 설정에 차이가 있어야합니다. :-)

내 설정에 대해 설명하겠습니다. 아마도 당신에게 리드를 줄 수 있습니다.

  1. @IBOutlets활성화 / 활성화하는 데 필요한 모든 제약 조건을 설정했습니다 .
  2. 에서는 ViewController약하지 않은 클래스 속성에 제약 조건을 저장합니다. 그 이유는 제약 조건을 한 후 다시 활성화 할 수 있습니다. 따라서 당신이 얻게 될 것입니다.
  3. 나는 NSLayoutConstraint.deactivate/activate당신처럼 사용하지 않고 대신 constraint.active = YES/를 NO사용합니다.
  4. 제약 조건을 설정 한 후 view.layoutIfNeeded().

어쩌면 당신은 할 수 귀하의 확인 @properties, 교체 weak와 함께strong .

거기에 active = NO설정 되어 다시 self.yourConstraint = nil사용할 수 없습니다 self.yourConstraint.


override func viewDidLayoutSubviews() {
// do it here, after constraints have been materialized
}

나는 당신이 겪고있는 문제는 AFTER viewDidLoad()가 호출 될 때까지 그들의 뷰에 추가되지 않는 제약 때문이라고 생각합니다 . 다음과 같은 여러 옵션이 있습니다.

A) 레이아웃 제약 조건을 IBOutlet에 연결하고 성능 참조를 통해 코드에서 액세스 할 수 있습니다. 콘센트는 viewDidLoad()킥오프 전에 연결되어 있으므로 제약 조건에 액세스 할 수 있고 계속해서 활성화 및 할 수 있습니다.

비)constraints()다양한 제약 조건에 액세스 하기 위해 UIView의 기능을 사용 하기 위해 viewDidLayoutSubviews()시작 하기 기다려야 합니다. 그것이 뷰 제약 조건이있는 펜촉에서 컨트롤러를 만든 후 첫 번째 지점이기 때문입니다. layoutIfNeeded()완료되면 전화하는 것을 잊지 않습니다 . 이 적용 할 변경 사항이있는 경우 레이아웃 패스가 두 번 수행 많은 장애가 있고 무한 루프가 트리거 될 가능성이 있는지 확인해야합니다.

간단한 경고 : 반환 된 제약 조건은 방법 의해 반환됩니다 constraints() ! 즉, 나중에 다시 켜려는 의도로 제약 조건을 유지해야합니다.

C) 스토리 보드 접근 방식을 버리고 대신 수동으로 제약 조건을 추가 할 수 있습니다. 이 작업을 수행하고 viewDidLoad()따라서 즉시 레이아웃을 변경하는 대신 수행의 전체 수명 동안 한 번만 수행하는 가정에서 허용 가능한 방법을 수행합니다.


priority속성을 "활성화"및 "비활성화"하도록 조정할 수도 있습니다 (예 : 활성화하려면 750 값, 비활성화하려면 250). 어떤 뮤지션 activeBOOL을 변경해도 UI에 영향을 미칠 가능성이 있습니다. 필요 layoutIfNeeded하지 않습니다. viewDidLoad 또는 그 이후에 마케팅 및 방송 수 있습니다.


사용하지 않는 제약 조건을 중단하는 시간 :

-(void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];

    self.myLittleConstraint.active = NO;
}

명심 viewWillLayoutSubviews좋아, 무거운 계산, 여러 번 호출 할 수 있는지?

참고 : 나중에 제약 조건 중 일부를 다시 선택하여 항상 strong참조를 저장 합니다.


뷰가 생성 될 때 다음 라이프 사이클 메소드가 순서대로 호출됩니다.

  1. loadView
  2. viewDidLoad
  3. viewWillAppear
  4. viewWillLayoutSubviews
  5. viewDidLayoutSubviews
  6. viewDidAppear

이제 귀하의 질문에.

  1. 이 동작이 발생하는 이유는 무엇입니까?

답 : 뷰의 뷰에 대한 제약을 설정 viewDidLoad하려고 할 때 뷰의 경계가 있습니다. viewDidLayoutSubviews뷰의 경계가 참조 된 후에 합니다.

  1. viewDidLoad에서 제약 조건을 활성화 / 할 수 있습니까?

답변 : 아니요. 위에 설명 된 이유.


활성 및 비활성 제약 조건을 사용하는 초기성에 - (void)updateConstraints대한 strong참조 와 함께 (목표 c) 재정의에서 정상 당 제약 조건을 설정하는 한 발견했습니다 . 뷰 사이클의 다른 곳에서 필요한 것을 비활성화 및 / 또는 활성화 한 다음을 호출 layoutIfNeeded하면 문제가 없어야합니다.

가장 중요한 것은 첫 번째 초기화 및 레이아웃 후에 s updateConstraints를 호출하는 한 제약 조건 의 재정의를 지속적으로 재사용하지 않고 제약 조건의 활성화를 분리하는 것 updateConstraint입니다. 그 후에는 뷰 사이클에서 중요한 것 같습니다.

참고 URL : https://stackoverflow.com/questions/27494542/when-can-i-activate-deactivate-layout-constraints

반응형