2014-10-02 6 views
2

키보드가 위로 올라 갔을 때 높이 변경을 애니메이션으로 표시하려고하는보기가 있습니다 (아래 표시된 코드). 프레임 변경을 호출하는 뷰는 완벽하게 애니메이션입니다. 그러나이보기에는 하위보기가 포함되어 있으며이보기에는 키보드가 나타나는 텍스트 필드가 포함되어 있으며 이러한 하위보기는 애니메이션 대신 새 위치로 점프하고 있습니다. 하위 뷰에 자동 레이아웃 제약 조건을 넣어 수퍼 뷰의 왼쪽, 아래 및 오른쪽으로 제한하고 일정한 높이를 유지합니다. 여기iOS - 서브 프레임이 프레임 변경으로 애니메이션되지 않습니다.

예 비디오 : http://youtu.be/EmcZ-cXeTbM

#import "ViewController.h" 

@interface ViewController() 

@end 

@implementation ViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(slideViewForKeyboard:) name:UIKeyboardWillShowNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(slideViewForKeyboard:) name:UIKeyboardWillHideNotification object:nil]; 
} 
- (void)slideViewForKeyboard:(NSNotification *)note { 
    NSDictionary* userInfo = [note userInfo]; 

    // Get animation info from userInfo 
    NSTimeInterval animationDuration; 
    UIViewAnimationCurve animationCurve;  
    CGRect keyboardEndFrame; 

    [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve]; 
    [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration]; 
    [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame]; 

    CGRect newFrame = CGRectMake(self.view.frame.origin.x, 
           self.view.frame.origin.y, 
           self.view.frame.size.width, 
           keyboardEndFrame.origin.y); 

    [UIView animateWithDuration:0 delay:0 options:(animationCurve << 16) animations:^{ 
     [self.view setFrame:newFrame]; 
    }completion:^(BOOL completed){}]; 
} 
- (IBAction)endEditingOnTap:(UITapGestureRecognizer *)sender { 
    [self.view endEditing:YES]; 
} 

@end 

답변

6

애니메이션 블록의 지속 시간으로 animationDuration을 사용해야합니다.

그 외에도 다른 문제가 있습니다. 지금은 애니메이션 블록 안에 뷰 프레임을 설정하여 변경 사항이 애니메이션으로 표시됩니다. 그러나 시스템은 실행 루프의 레이아웃 단계에서 나중에 애니메이션 블록 외부로 서브 뷰를 배치합니다. 즉, 하위 뷰는 새로운 프레임으로 애니메이션되지 않습니다.

당신은 애니메이션 블록 내보기에 layoutIfNeeded를 전송하여 해당 문제를 해결할 수 :

[UIView animateWithDuration:animationDuration delay:0 options:(animationCurve << 16) animations:^{ 
    self.view.frame = newFrame; 
    [self.view layoutIfNeeded]; 
} completion:^(BOOL completed){}]; 

그러나 당신은 아마 또 다른 문제로 실행하겠습니다. 뷰의 프레임을 직접 설정하고 있지만 자동 레이아웃을 사용하고 있습니다. 어떤 시점에서, 자동 레이아웃은 아마 귀하의 제약 조건에 따라 프레임을 다시 설정할 것입니다. 프레임을 직접 설정하는 대신 새 프레임을 제어하기 위해보기의 제한 조건을 수정해야합니다.

+0

감사합니다. -layoutIfNeeded는 내가 필요한 것입니다. (animationDuration은 코드를 SO로 바꿨을 때 오타 였지만 그 캐치에도 감사드립니다!) –

0

설정 애니메이션 기간입니다.

[UIView animateWithDuration:0.3 delay:0 options:(animationCurve << 16) animations:^{ 
      [self.view setFrame:newFrame]; 
     }completion:^(BOOL completed){}]; 
0

0에서 -[UIView animateWithDuration:delay:options:animations:completion]으로 전달됩니다. 프레임 0에서 프레임 n-1 (여기서 n은 생성했을 프레임의 수)에서 0 초 (순간적으로)로 이동하므로 애니메이션이 생성되지 않습니다. animationDuration을 인수로 사용하여 키보드와 동일한 속도로 애니메이션을 재생하십시오.

관련 문제