0

게시 할 가치가있는 코드를 리팩터링 한 후 이상한 문제가 발생하여 하루 종일 미치게 만듭니다.Animating TextView 포커스 변경 후 UIView가 프레임 위치를 변경합니다.

서브 테이블이있는 UIView가 포함 된 XIB가있는 재사용 가능한 사용자 정의 컨트롤이 있습니다. 3 UITextField (UserName, Password, Email), 가입 입력란이라고 가정합니다. 키보드에서 작동하려면 UITextFieldDelegate를 따릅니다. 다음으로 키보드 버튼을 누릅니다.

내 모든 견해에서 나는 크게 AutoLayout 제약을 신중하게 사용합니다.

파일 소유자의 UIView 자손 사용자 정의 클래스 (SignUpInputView.m)에서 내 펜촉을 초기화합니다.

- (void) setupView 
    { 
    self.view = [self loadViewFromNib]; 
    self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 
    self.bounds = self.view.bounds; 
    _intrinsicContentSize = self.bounds.size; 
    [self setTranslatesAutoresizingMaskIntoConstraints:NO]; 
    self.view.layer.borderWidth = 1.0f; 
    self.view.layer.borderColor = [self greyColor]; 
    [self setupOutlets]; // I set the UITextFields delegate 
    [self addSubview:self.view]; 
    } 

// Override the intrinsicContectSize method 

- (CGSize)intrinsicContentSize 
    { 
    return _intrinsicContentSize; 
    } 

BaseViewController에서 파생 된 LoginViewController에서 getter 메서드를 설정하는 속성을 가진 사용자 지정 컨트롤을 사용합니다.

@property (strong, nonatomic, getter=getSignUpInputView) SignUpInputView* signUpInputView; 

- (SignUpInputView*) getSignUpInputView 
    { 
    if (!_signUpInputView) 
     { 
     _signUpInputView = [SSESignUpInputView new]; 
     _signUpInputView.hidden = YES; 
     _signUpInputView.alpha = 0.0f; 
     [self.view addSubview:_signUpInputView]; 
     [self.view addConstraint:[NSLayoutConstraint constraintWithItem:_signUpInputView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0f constant:0.0f]]; 
     [self.view addConstraint:[NSLayoutConstraint constraintWithItem:_signUpInputView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0f constant:0.0f]]; 
     [self.view addConstraint:[NSLayoutConstraint constraintWithItem:_signUpInputView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:1.0f constant:0.0f]]; 
     [_signUpInputView addConstraint:[NSLayoutConstraint constraintWithItem:_signUpInputView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:_signUpInputView attribute:NSLayoutAttributeHeight multiplier:1.0f constant:0.0f]]; 
     } 
    return _signUpInputView; 
    } 

나는 (취소 버튼, 푸시 가입 버튼) 사용자가 조치를 취에 따라 SignUpViewController에 숨겨진 알파 속성을 처리합니다.

SignUpViewController에는 사용자가 SignUp 버튼을 누르면 메소드가 있습니다.

- (IBAction)signupButtonTouchUpInside:(UIButton*)sender 
    { 
    // Call a method that sets some animations 

    // Set some other animations here. 
    [self.view layoutIfNeeded]; 
    [UIView transitionWithView:self.uploadPhotoButton duration:1.0f options:UIViewAnimationOptionTransitionFlipFromRight animations: 
     ^{ 
     self.aView.alpha = 1.0f; 
     self.anotherView.alpha = 0.0f; 
     [self.view layoutIfNeeded]; 
     } 
    completion:nil]; 

    SignUpInputView* signUpView = self.signUpInputView; 
    signUpView.hidden = NO; 
    [signUpView fullNameBecomeFirstResponder]; 
    // This is a method from the BaseViewController 
    [super animateViewFromLeftOffsetOnTopOfKeyboard:signUpView]; 
    } 

BaseViewController animateViewFromLeftOffsetOnTopOfKeyboard : 구현.

- (void) animateViewFromLeftOffsetOnTopOfKeyboard:(UIView*)view 
    { 
    // Execute with some delay to make sure I have the keyboard's height from the UIKeyboardDidChangeFrameNotification 
    [self executeBlock: 
     ^{ 
     CGFloat yInputView = self.view.bounds.size.height - [self keyboardHeight] - view.bounds.size.height/2; 
     view.center = CGPointMake(-view.bounds.size.width, yInputView); 
     view.alpha = 1.0f; 
     [self.view layoutIfNeeded]; 
     [UIView animateWithDuration:1.0f delay:0.0f usingSpringWithDamping:0.8f initialSpringVelocity:0.0f options:UIViewAnimationOptionCurveEaseOut animations: 
      ^{ 
      view.center = CGPointMake(view.bounds.size.width/2, yInputView); 
      [self.view layoutIfNeeded]; 
      } 
     completion:nil]; 
     } 
    withDelay:0.7]; 
    } 

모든 달콤한 작동하지만 지금은 그것 같이이 오류가 animateViewFromLeftOffsetOnTopOfKeyboard: 방법의 [UIView animateWithDuration:] 코드 블록에서 view.center = CGPointMake(view.bounds.size.width/2, yInputView);을 유지하지 않습니다 있습니다.

문제는 초기 UITextField (전체 이름, signupButtonTouchUpInside: 메서드에서 위의 코드 참조) 이외의 텍스트 필드를 탭하면 SignUpInputView가 즉시 화면의 맨 위로 이동합니다.

나는 뭔가를 놓치고 있지만, 두 번 제약 조건을 추가하는 중 충돌과 다른 일반적인 숨겨진 알파 속성 조작 때문에 NSLayoutConstraints를 BaseController에서 getter 속성 메서드로 리팩터링하기 전에 작업 중이었습니다.

+0

내 대답보기, http://stackoverflow.com/questions/18245878/weird-behaviour-happens-when-using-uiview-animate-and-cgaffinetransform/18246174#18246174 – rdelmar

+0

OK, 자동 레이아웃 사용 중지 문제의 센스를 바꾸면 프레임이 바뀝니다. 그래서 프레임을 서브 뷰에 추가하기 전에 프레임을 설정 한 다음, 제약 조건을 애니메이션화하면 (아마도 가로 세로 가운데 하나) 내 문제가 해결됩니다. 비록 내가 UIView의 정확한 위치를 알지는 못했지만 나에게 도전을 소개한다. 이견있는 사람? –

+0

프레임을 전혀 설정하지 마십시오. 하위 뷰를 추가하고 초기 위치를 설정하는 데 제약 조건을 지정합니다. 수정할 제약 조건에 대한 속성을 만듭니다. 이러한 제약 조건의 상수 값을 원하는대로 변경 한 다음 애니메이션 블록에서 layoutIFNeeded를 호출합니다. – rdelmar

답변

1

이 시나리오에서는 프레임을 설정하지 않아야합니다. 하위 뷰를 추가하고 초기 위치를 설정하는 데 제약 조건을 지정합니다. 수정할 제약 조건에 대한 속성을 만듭니다. 뷰를 애니메이션화하려면 해당 제약 조건의 상수 값을 원하는 값으로 변경 한 다음 애니메이션 블록에서 layoutIFNeeded를 호출합니다.

관련 문제