NSLayoutConstraints는 애니메이션 가능합니까? [복제]
이 질문에는 이미 답변이 있습니다.
- 구속 조건 변경에 애니메이션을 적용하려면 어떻게합니까? 답변 13 개
풍경의 거대한 키보드에 의해 차단되도록 일부 뷰를 애니메이션하려고합니다. 프레임에 단순히 애니메이션을 적용하면 잘 작동하지만 다른 사람들은 이것이 비생산적이며 대신 NSLayoutConstraints를 업데이트해야한다고 제안했습니다. 그러나 애니메이션 효과가없는 것 같습니다. 누구든지 성공을 위해 일하게 되었습니까?
//heightFromTop is an NSLayoutConstraint referenced from IB
[UIView animateWithDuration:0.25 animations:^{
self.heightFromTop.constant= 550.f;
}];
결과적으로 문제의 높이로 즉시 점프합니다.
이 정확한 패턴을 따르십시오.
self.heightFromTop.constant = 550.0f;
[myView setNeedsUpdateConstraints];
[UIView animateWithDuration:0.25f animations:^{
[myView layoutIfNeeded];
}];
여기서 myView도면이다 self.heightFromTop첨가 하였다. 애니메이션 블록에서 수행 한 유일한 작업은 구속 조건을 설정하는 것이기 때문에 레이아웃이 즉시 발생하지 않으므로 뷰가 "점프"합니다. 코드에서을 설정 한 후 다음 실행 루프에서 레이아웃이 발생 heightFromTop.constant하며 그 시간까지 이미 애니메이션 블록 범위를 벗어납니다.
스위프트 2에서 :
self.heightFromTop.constant = 550
myView.setNeedsUpdateConstraints()
UIView.animateWithDuration(0.25, animations: {
myView.layoutIfNeeded()
})
Apple이 제안한 방법은 약간 다릅니다 ( 예 : "자동 레이아웃으로 변경 한 애니메이션 애니메이션"섹션 참조 ). 먼저 애니메이션 전에 layoutIfNeeded를 호출해야합니다. 그런 다음 애니메이션 블록 안에 애니메이션을 추가 한 다음 마지막에 layoutIfNeeded를 다시 호출하십시오. 자동 레이아웃으로 전환하는 나와 같은 사람들에게는 애니메이션 블록 내부의 프레임으로 수행했던 이전 애니메이션과 더 유사한 방법입니다. 애니메이션 전과 애니메이션 후에 layoutIfNeeded를 두 번 호출하면됩니다.
[self.view layoutIfNeeded]; // Ensures that all pending layout operations have been completed
[UIView animateWithDuration:1.0f animations:^{
// Make all constraint changes here
self.heightFromTop.constant= 550.f;
[self.view layoutIfNeeded]; // Forces the layout of the subtree animation block and then captures all of the frame changes
}];
@Centurion의 접근 방식을 시도했지만 스토리 보드에서로드 된 경우 어떻게 든 내보기가 잘못된 프레임으로 애니메이션됩니다. 첫 번째 layoutIfNeeded를 로 바꾸면 문제가 사라지 updateConstraintsIfNeeded지만 이유는 모르겠습니다. 누구나 설명을 할 수 있다면 대단히 감사하겠습니다.
[self.view updateConstraintsIfNeeded];
[UIView animateWithDuration:1.0 animations:^{
self.myConstraint.constant= 100;
[self.view layoutIfNeeded];
}];
나는 비슷한 문제가 있었고이 스레드는 그것을 극복하는 데 큰 도움이되었습니다.
erurainon의 답변이 올바른 길로 안내되었지만 약간 다른 답변을 제안하고 싶습니다. erurainon의 제안 된 코드는 애니메이션 전환 대신 점프가 있었기 때문에 나에게는 효과가 없었습니다. cnotethegr8에서 제공하는 링크를 통해 실제 답변을 얻을 수 있습니다.
자동 레이아웃 설명서 https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/AutoLayoutbyExample/AutoLayoutbyExample.html (페이지 하단까지)
Erurainon의 답변과 몇 가지 차이점 :
- 애니메이션 메서드를 호출하기 전에 컨테이너 뷰에서 레이아웃 레이아웃을 호출합니다 (myView의 setNeedsUpdateConstraints 대신).
- 애니메이션 블록에서 새로운 구속 조건을 설정하십시오.
- myView 대신 애니메이션 메서드의 컨테이너보기에서 제약 조건을 설정 한 후 layoutIfNeeded를 호출하십시오.
위 링크에서 Apple이 제안한 패턴을 준수합니다.
예
I wanted to animate a particular view, closing or expanding it at the click of a button. Since I'm using autolayout and didn't want to hard code any dimensions (in my case height) in the code, I decided to capture the height in viewDidLayoutSubviews. You need to use this method and not viewWillAppear when using autolayout. Since viewDidLayoutSubviews may be called many times, I used a BOOL to let me know about the first execution for my initialization.
// Code snippets
@property (weak, nonatomic) IBOutlet UIView *topView; // Container for minimalView
@property (weak, nonatomic) IBOutlet UIView *minimalView; // View to animate
@property (nonatomic) CGFloat minimalViewFullHeight; // Original height of minimalView
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *minimalViewHeightConstraint;
@property (nonatomic) BOOL executedViewDidLayoutSubviews;
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
// First execution of viewDidLayoutSubviews?
if(!self.executedViewDidLayoutSubviews){
self.executedViewDidLayoutSubviews = YES;
// Record some original dimensions
self.minimalViewFullHeight = self.minimalView.bounds.size.height;
// Setup our initial view configuration & let system know that
// constraints need to be updated.
self.minimalViewHeightConstraint.constant = 0.0;
[self.minimalView setNeedsUpdateConstraints];
[self.topView layoutIfNeeded];
}
}
Resize full action snippet
// An action to close our minimal view and show our normal (full) view
- (IBAction)resizeFullAction:(UIButton *)sender {
[self.topView layoutIfNeeded];
[UIView transitionWithView:self.minimalView
duration:1.0
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.minimalViewHeightConstraint.constant = 0.0;
// Following call to setNeedsUpdateConstraints may not be necessary
[self.minimalView setNeedsUpdateConstraints];
[self.topView layoutIfNeeded];
} completion:^(BOOL finished) {
;
}];
// Other code to show full view
// ...
}
Resize small action snippet
// An action to open our minimal view and hide our normal (full) view
- (IBAction)resizeSmallAction:(UIButton *)sender {
[self.topView layoutIfNeeded];
[UIView transitionWithView:self.minimalView
duration:1.0
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.minimalViewHeightConstraint.constant = self.minimalViewFullHeight;
[self.minimalView setNeedsUpdateConstraints];
[self.topView layoutIfNeeded];
} completion:^(BOOL finished) {
;
}];
// Other code to hide full view
// ...
}
You can use animateWithDuration instead of transitionWithView if you wish.
Hope this helps.
참고URL : https://stackoverflow.com/questions/12926566/are-nslayoutconstraints-animatable
'Programming' 카테고리의 다른 글
| git에서 마지막 커밋을 취소하는 방법 (0) | 2020.05.10 |
|---|---|
| Windows에서 추가 캐리지 리턴을 추가하는 Python의 CSV (0) | 2020.05.10 |
| iPhone 방향이 세로에서 가로로 변경 될 때 HTML 글꼴 크기 유지 (0) | 2020.05.10 |
| C에서 소수점 이하 2 자리로 반올림 (0) | 2020.05.10 |
| ActiveRecord / Rails로 NOT IN 쿼리를 표현하는 방법? (0) | 2020.05.10 |