0

キーボードをかわすためUITextViewに を使用しているがあります。NSLayoutConstraint制約は次のとおりです。

self.textViewBottomConstraint = [NSLayoutConstraint constraintWithItem:textView
                                                    attribute:NSLayoutAttributeBottom
                                                    relatedBy:NSLayoutRelationEqual
                                                       toItem:self.view
                                                    attribute:NSLayoutAttributeBottom
                                                   multiplier:1.0
                                                     constant:0.0];
[self.view addConstraint:self.textViewBottomConstraint];

キーボードが表示/非表示になると、制約定数をキーボードの高さに設定して制約をアニメーション化します。ただし、これを行うと何らかの理由で contentSize が {0,0} にリセットされ、スクロールが中断されます。contentSize をリセット前の状態にリセットするためのハックを追加しましたhandleKeyboardDidHide:が、これには、スクロール位置がリセットされたり、入力が開始されるまでビューがカーソル位置にスクロールされないなど、いくつかの醜い副作用があります。

- (void) handleKeyboardDidShow:(NSNotification *)notification
{
     CGFloat height = [KeyboardObserver sharedInstance].keyboardFrame.size.height;
     self.textView.constant = -height;
     [self.view layoutIfNeeded];
}

- (void) handleKeyboardDidHide:(NSNotification *)notification
{
   // for some reason, setting the bottom constraint resets the contentSize to {0,0}...
   // so let's save it before and reset it after.
   // HACK
   CGSize size = self.textView.contentSize;
   self.textView.constant = 0.0;
   [self.view layoutIfNeeded];
   self.textView.contentSize = size;
}

この問題を完全に回避する方法を知っている人はいますか?

4

1 に答える 1

1

あなたのコードの何が問題なのかわかりません。必要に応じて詳細に対処できます。ただし、最初の提案として、可能であれば、UITextView のサイズを変更しないでください。次のように、コンテンツを変更してインセットをスクロールするだけです。

- (void) keyboardShow: (NSNotification*) n {
    NSDictionary* d = [n userInfo];
    CGRect r = [d[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    self.tv.contentInset = UIEdgeInsetsMake(0,0,r.size.height,0);
    self.tv.scrollIndicatorInsets = UIEdgeInsetsMake(0,0,r.size.height,0);
}

それでも、これらの値をリセットする前に、キーボードの非表示アニメーションが完了するまで待つ必要があることがわかりました。

- (void) keyboardHide: (NSNotification*) n {
    NSDictionary* d = [n userInfo];
    NSNumber* curve = d[UIKeyboardAnimationCurveUserInfoKey];
    NSNumber* duration = d[UIKeyboardAnimationDurationUserInfoKey];
    [UIView animateWithDuration:duration.floatValue delay:0
                        options:curve.integerValue << 16
                     animations:
     ^{
         [self.tv setContentOffset:CGPointZero];
     } completion:^(BOOL finished) {
         self.tv.contentInset = UIEdgeInsetsZero;
         self.tv.scrollIndicatorInsets = UIEdgeInsetsZero;
     }];
}

(そのトリックが何らかの形であなたのコードにも役立つかもしれません。)

于 2013-04-11T22:51:43.767 に答える