web-dev-qa-db-ja.com

iOS 7-キーボードアニメーション

IPhone 5シミュレータ上のiOS 7.0の新しいキーボードアニメーションを理解しようとしています。キーボードが表示されたらUITableViewのサイズを変更したいのですが、正しいアニメーションの詳細を取得できません。
キーボードが表示または非表示になったときに、NSNotificationオブジェクトの情報を使用しています。

ここに私のログがあります:

Move keyboard from {{0, 920}, {320, 216}} to {{0, 352}, {320, 216}}
 with duration: 0.400000
 and animation curve: 7

UIViewAnimationCurveEaseInOut = 0
UIViewAnimationCurveEaseIn = 1
UIViewAnimationCurveEaseOut = 2
UIViewAnimationCurveLinear = 3

アニメーションカーブは不明な値です。どうすればよいですか?

47
Paul Warkentin

今、私は解決策を見つけました。アニメーションは{0, 920}から{0, 352}の地点から始まります。問題は、UITableViewオブジェクトが{160, 568}のサイズで開始したため、アニメーションが開始される前にUITableViewのサイズを{160, 920}に変更したことです。

未知のアニメーションカーブに関しては、パラメータをanimationCurve << 16に設定して、ビューアニメーションカーブからビューアニメーションオプションに変換するだけです。
値は、線形、イーズイン、イーズアウト、イージングアウトのアニメーション曲線と等しくありません。

ここに私のコードがあります:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(_keyboardWillShow:)
                                             name:UIKeyboardWillShowNotification
                                           object:nil];

そして:

- (void)keyboardWillShow:(NSNotification *)aNotification {
    NSDictionary *userInfo = aNotification.userInfo;

    //
    // Get keyboard size.

    NSValue *beginFrameValue = userInfo[UIKeyboardFrameBeginUserInfoKey];
    CGRect keyboardBeginFrame = [self.view convertRect:beginFrameValue.CGRectValue fromView:nil];

    NSValue *endFrameValue = userInfo[UIKeyboardFrameEndUserInfoKey];
    CGRect keyboardEndFrame = [self.view convertRect:endFrameValue.CGRectValue fromView:nil];

    //
    // Get keyboard animation.

    NSNumber *durationValue = userInfo[UIKeyboardAnimationDurationUserInfoKey];
    NSTimeInterval animationDuration = durationValue.doubleValue;

    NSNumber *curveValue = userInfo[UIKeyboardAnimationCurveUserInfoKey];
    UIViewAnimationCurve animationCurve = curveValue.intValue;

    //
    // Create animation.

    CGRect tableViewFrame = self.tableView.frame;
    bTableViewFrame.size.height = (keyboardBeginFrame.Origin.y - tableViewFrame.Origin.y);
    self.tableView.frame = tableViewFrame;

    void (^animations)() = ^() {
        CGRect tableViewFrame = self.tableView.frame;
        tableViewFrame.size.height = (keyboardEndFrame.Origin.y - tableViewFrame.Origin.y);
        self.tableView.frame = tableViewFrame;
    };

    //
    // Begin animation.

    [UIView animateWithDuration:animationDuration
                          delay:0.0
                        options:(animationCurve << 16)
                     animations:animations
                     completion:nil];
}
47
Paul Warkentin

IOS 7では、キーボードは文書化されていない新しいアニメーションカーブを使用します。アニメーションオプションに文書化されていない値を使用することに気づいている人もいますが、私は次のものを使用することを好みます。

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
[UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
[UIView setAnimationBeginsFromCurrentState:YES];

// work

[UIView commitAnimations];

ブロックベースのアニメーションが推奨ですが、キーボード通知から返されるアニメーション曲線はUIViewAnimationCurveですが、ブロックベースのアニメーションに渡す必要があるオプションはUIViewAnimationOptionsです。従来のUIViewアニメーションメソッドを使用すると、値を直接パイプで渡すことができます。最も重要なことは、これは新しいドキュメント化されていないアニメーション曲線(整数値7)。また、iOS 6および7でも同様に機能します。

72
David Beck

animateWithDurationブロックを使用して、その中に曲線を設定できます。それはきれいで、うまく機能します。

UIViewAnimationCurve curve = [[notification.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
double duration = [[notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];

[UIView animateWithDuration:duration
                    delay:0
                  options:UIViewAnimationOptionBeginFromCurrentState 
               animations:^{
                 [UIView setAnimationCurve:curve];
                 /* ANIMATION HERE */
                 // don't forget layoutIfNeeded if you use autolayout
               }
               completion:nil];

ハッピーコーディング!

[〜#〜] update [〜#〜]

私が書いたシンプルなUIViewControllerカテゴリを使用できます https://github.com/Just-/UIViewController-KeyboardAnimation

12
Anton Gaenko

代わりにUIKeyboardWillChangeFrameNotificationを使用します。中国語キーボードなどの一部の国際キーボードは使用中に高さが変わるためです。また、このコードは、横向きモードでもキーボードの正しい高さを提供します。 (注:以下のコードはAutolayout向けです)

//set your observer, in a method like viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChange:) name:UIKeyboardWillChangeFrameNotification object:nil];

- (void)keyboardWillChange:(NSNotification *)notification {
    CGRect initialRect = [notification.userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
    CGFloat initialHeight = self.view.frame.size.height - [self.view convertRect:initialRect fromView:nil].Origin.y;
    CGRect keyboardRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    CGFloat newHeight = self.view.frame.size.height - [self.view convertRect:keyboardRect fromView:nil].Origin.y;
    //set your constraints here, based on initialHeight and newHeight, which are the heights of the keyboard before & after animation.
    [self.contentView setNeedsUpdateConstraints];
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    [UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [self.contentView layoutIfNeeded];
    [UIView commitAnimations];
}
5
Jeffrey Sun

キーボードと同じアニメーションを使用するには、文書化されていない曲線オプションを使用する必要があります。

- (void)keyboardWillHide:(NSNotification *)notification {
    NSDictionary *userInfo = [notification userInfo];

    CGRect rect = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    NSTimeInterval animationDuration = [[userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    NSInteger curve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue] << 16;

    [UIView animateWithDuration:animationDuration delay:0.0 options:curve animations:^{

    } completion:nil];
}

実際にメソッドanimateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:は、すべてのアニメーションがiOS7およびiOS8で実行される新しい方法です。適切な持続時間、減衰、速度を設定するだけで、同じ効果が得られますが、速度/時間を変更することもできます。

4
invoodoo

In Swift 4

キーボード通知のオブザーバーを追加します。

  • UIKeyboardDidShowNotification
  • UIKeyboardDidHideNotification

via

NSNotificationCenter.defaultCenter().addObserver(_ observer: Any, 
        selector aSelector: Selector, 
        name aName: NSNotification.Name?, 
        object anObject: Any?)

セレクターを実装して、キーボードアニメーションでUIをアニメーション化します。有効なカーブ値を作成するには、UIResponder.keyboardAnimationCurveUserInfoKeyを<< 16だけシフトする必要があります

func keyboardWillShow(_ notification: Notification!) {
    if let info = notification.userInfo {
        let keyboardSize = info[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect
        let duration = info[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double 
        let curveVal = (info[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber)?.intValue ?? 7 // default value for keyboard animation
        let options = UIView.AnimationOptions(rawValue: UInt(curveVal << 16))
        UIView.animate(withDuration: duration, delay: 0, options: options, animations: {
        // any operation to be performed
    }, completion: nil)
    }
}
2
Anu Mittal

通知の登録:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];

ビューのframe.Origin.yへの変更をアニメーション化して応答します。

- (void)keyboardWillShow:(NSNotification *)aNotification {

    NSDictionary *userInfo = aNotification.userInfo;
    NSValue *endFrameValue = userInfo[UIKeyboardFrameEndUserInfoKey];
    CGRect keyboardEndFrame = [self.view convertRect:endFrameValue.CGRectValue fromView:nil];

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:[aNotification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    [UIView setAnimationCurve:[aNotification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
    [UIView setAnimationBeginsFromCurrentState:YES];

    CGRect searchButtonFrame = self.searchButton.frame;
    searchButtonFrame.Origin.y = (keyboardEndFrame.Origin.y - searchButtonFrame.size.height);
    self.searchButton.frame = searchButtonFrame;

    [UIView commitAnimations];
}
0