programing

NS 레이아웃 제약 조건은 애니메이션으로 제작할 수 있습니까?

bestprogram 2023. 7. 16. 13:44

NS 레이아웃 제약 조건은 애니메이션으로 제작할 수 있습니까?

저는 몇몇 뷰들을 애니메이션으로 만들어서 가로로 된 거대한 키보드에 의해 차단되도록 하려고 합니다.단순히 프레임을 애니메이션화하면 잘 작동하지만, 다른 사람들은 이것이 역효과를 낳기 때문에 대신 NS 레이아웃 제약 조건을 업데이트해야 한다고 제안했습니다.하지만, 그들은 생명체가 될 수 없는 것처럼 보입니다.누가 그들을 성공적으로 일하게 했나요?

//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그리고 그 때쯤이면 이미 애니메이션 블록의 범위 밖에 있는 것입니다.

Swift 2에서:

self.heightFromTop.constant = 550
myView.setNeedsUpdateConstraints()

UIView.animateWithDuration(0.25, animations: {
   myView.layoutIfNeeded()
})

Apple에서 제안하는 방법은 조금 다릅니다("자동 레이아웃에 의해 변경된 애니메이션 작성" 섹션의 참조).애니메이션을 만들기 전에 먼저 layoutIfNeed를 호출해야 합니다.그런 다음 애니메이션 블록 안에 애니메이션 내용을 추가한 다음 마지막에 layoutIfNeed를 다시 호출합니다.저처럼 자동 레이아웃으로 전환하는 사람들에게, 이것은 애니메이션 블록 안에 있는 프레임으로 우리가 했던 이전의 애니메이션과 더 유사한 방식입니다.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의 답변은 저를 올바른 방향으로 이끌었지만, 저는 약간 다른 답변을 제안하고 싶습니다.에루레이온에서 제안된 코드는 애니메이션 전환 대신 점프를 계속했기 때문에 저에게 효과가 없었습니다.cote thegr8에서 제공한 링크는 제게 작업 답변을 주었습니다.

Auto Layout Guide https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/AutoLayoutbyExample/AutoLayoutbyExample.html (페이지 하단까지).

오류에 의한 답변과 몇 가지 차이점:

  1. 애니메이션 메서드를 호출하기 전에 컨테이너 보기에서 콜 레이아웃이 필요한 경우(및 myView에서 설정하는 대신 업데이트 제약 조건이 필요함).
  2. 애니메이션 블록에서 새 제약 조건을 설정합니다.
  3. myView가 아닌 애니메이션 메소드(제약 조건을 설정한 후)의 컨테이너 보기에서 layoutIfRequired를 호출합니다.

이는 위 링크에서 Apple이 제안한 패턴을 준수합니다.

예문

특정 보기를 클릭하여 닫거나 확장하여 특정 보기를 애니메이션화하고 싶었습니다.자동 레이아웃을 사용하고 있고 코드의 차원(내 경우 높이)을 하드 코딩하고 싶지 않았기 때문에 DidLayoutSubviews 보기에서 높이를 캡처하기로 결정했습니다.자동 레이아웃을 사용할 때는 이 메서드를 사용해야 하며 WillApear를 볼 수 없습니다.viewDidLayoutSubviews는 여러 번 호출될 수 있기 때문에 BOOL을 사용하여 초기화를 위한 첫 번째 실행에 대해 알려주었습니다.

// 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];
    }
}

전체 작업 스니펫 크기 조정

// 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
    // ...
}

작은 작업 스니펫 크기 조정

// 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
        // ...
    }

애니메이션을 사용할 수 있습니다.전환 대신 지속 시간 사용원하는 경우 보기를 사용합니다.

이게 도움이 되길 바랍니다.

언급URL : https://stackoverflow.com/questions/12926566/are-nslayoutconstraints-animatable