IB에 여러 제약 조건 세트를 설정했으며 일부 상태에 따라 프로그래밍 방식으로 전환하고 싶습니다. 거기의 constraintsA
IB에서 설치로 표시된 모두 출구 컬렉션, 그리고 constraintsB
모든 출구 수집은 IB에서 제거됩니다.
다음과 같이 프로그래밍 방식으로 두 세트간에 전환 할 수 있습니다.
NSLayoutConstraint.deactivateConstraints(constraintsA)
NSLayoutConstraint.activateConstraints(constraintsB)
근데 … 언제 해야할지 모르겠어요 . 에서 한 번 할 수 있어야 할 것 같지만 viewDidLoad
작동하지 않습니다. 나는 전화 해봤 view.updateConstraints()
및 view.layoutSubviews()
제약 조건을 설정 한 후,하지만 소용.
viewDidLayoutSubviews
모든 제약 조건을 설정하면 예상대로 작동 한다는 것을 알았습니다 . 두 가지를 알고 싶은 것 같아요 …
- 이 동작이 발생하는 이유는 무엇입니까?
- viewDidLoad에서 제약 조건을 활성화 / 비활성화 할 수 있습니까?
답변
에서 활성화 및 비활성화 NSLayoutConstraints
했는데 viewDidLoad
아무런 문제가 없습니다. 그래서 작동합니다. 앱과 내 앱 사이에 설정에 차이가 있어야합니다. 🙂
내 설정에 대해 설명하겠습니다. 아마도 당신에게 리드를 줄 수 있습니다.
@IBOutlets
활성화 / 비활성화하는 데 필요한 모든 제약 조건을 설정했습니다 .- 에서는
ViewController
약하지 않은 클래스 속성에 제약 조건을 저장합니다. 그 이유는 제약 조건을 비활성화 한 후 다시 활성화 할 수 없다는 것을 발견했기 때문입니다. 따라서 비활성화되면 삭제되는 것 같습니다. - 나는
NSLayoutConstraint.deactivate/activate
당신처럼 사용하지 않고 대신constraint.active = YES
/를NO
사용합니다. - 제약 조건을 설정 한 후
view.layoutIfNeeded()
.
답변
어쩌면 당신은 할 수 귀하의 확인 @properties
, 교체 weak
와 함께strong
.
때로는 active = NO
set 때문에 다시 self.yourConstraint = nil
사용할 수 없습니다 self.yourConstraint
.
답변
override func viewDidLayoutSubviews() {
// do it here, after constraints have been materialized
}
답변
나는 당신이 겪고있는 문제는 AFTER viewDidLoad()
가 호출 될 때까지 그들의 뷰에 추가되지 않는 제약 때문이라고 생각합니다 . 다음과 같은 여러 옵션이 있습니다.
A) 레이아웃 제약 조건을 IBOutlet에 연결하고 이러한 참조를 통해 코드에서 액세스 할 수 있습니다. 콘센트는 viewDidLoad()
킥오프 전에 연결되어 있으므로 제약 조건에 액세스 할 수 있어야하며 계속해서 활성화 및 비활성화 할 수 있습니다.
B)constraints()
다양한 제약 조건에 액세스 하기 위해 UIView의 기능을 사용하려면 viewDidLayoutSubviews()
시작 하기 를 기다려야 합니다. 그것이 설치된 제약 조건이있는 펜촉에서 뷰 컨트롤러를 만든 후 첫 번째 지점이기 때문입니다. layoutIfNeeded()
완료되면 전화하는 것을 잊지 마십시오 . 이것은 적용 할 변경 사항이있는 경우 레이아웃 패스가 두 번 수행된다는 단점이 있으며 무한 루프가 트리거 될 가능성이 없는지 확인해야합니다.
간단한 경고 : 비활성화 된 제약 조건은 메서드에 의해 반환되지 않습니다 constraints()
! 즉, 나중에 다시 켜려는 의도로 제약 조건을 비활성화하면 해당 참조를 유지해야합니다.
C) 스토리 보드 접근 방식을 잊어 버리고 대신 수동으로 제약 조건을 추가 할 수 있습니다. 이 작업을 수행하고 viewDidLoad()
있으므로 즉시 레이아웃을 변경하는 대신 객체의 전체 수명 동안 한 번만 수행하는 것으로 가정하므로 허용되는 방법이어야합니다.
답변
priority
속성을 “활성화”및 “비활성화”하도록 조정할 수도 있습니다 (예 : 활성화하려면 750 값, 비활성화하려면 250). 어떤 이유로 active
BOOL을 변경해도 UI에 영향을 미치지 않았습니다. 필요 layoutIfNeeded
하지 않으며 viewDidLoad 또는 그 이후에 언제든지 설정 및 변경할 수 있습니다.
답변
사용하지 않는 제약 조건을 비활성화하는 적절한 시간 :
-(void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
self.myLittleConstraint.active = NO;
}
명심 viewWillLayoutSubviews
좋아, 무거운 계산하므로, 여러 번 호출 할 수 있을까?
참고 : 나중에 제약 조건 중 일부를 다시 적용하려면 항상 strong
참조를 저장 하십시오.
답변
뷰가 생성 될 때 다음 라이프 사이클 메소드가 순서대로 호출됩니다.
- loadView
- viewDidLoad
- viewWillAppear
- viewWillLayoutSubviews
- viewDidLayoutSubviews
- viewDidAppear
이제 귀하의 질문에.
- 이 동작이 발생하는 이유는 무엇입니까?
답변 : 뷰의 뷰에 대한 제약을 설정하려고 할 때 viewDidLoad
뷰의 경계가 없으므로 제약을 설정할 수 없기 때문입니다. viewDidLayoutSubviews
뷰의 경계가 확정 된 후에야 합니다.
- viewDidLoad에서 제약 조건을 활성화 / 비활성화 할 수 있습니까?
답변 : 아니요. 위에 설명 된 이유.
