簡體   English   中英

在iOS7中邊緣滑動時,與UIView同步為鍵盤設置動畫

[英]Animate the keyboard in sync with the UIView while edge-swiping back in iOS7

我希望在iOS7中獲得類似於Messages app(在大多數短信應用程序中也很常見)的行為,在對話視圖中,從屏幕左邊緣向右滑動將表現得像UINavigationController中的后退按鈕。

我已設法實現此行為,但是,如果鍵盤在顯示視圖中打開,當我開始向后滑動時,鍵盤會卡住,並且在我移動手指時不會使視圖向右移動。 我想將鍵盤和呈現視圖設置為一個單元,而不是將鍵盤放在其他視圖的頂部,並且它們在它后面動畫,這就是我現在所獲得的(請參閱第二個屏幕截圖):

更新:請注意,在主視圖動畫完成后,鍵盤最終會消失;我關注的是滑動過程中鍵盤的位置,以及當您持續觸摸設備的一半時,不在與實際視圖同步。第二個屏幕截圖闡明了這種期望的行為。我也想知道它為什么不是默認行為。)

只需在Xcode 5.0.2中創建一個新的主 - 細節iPhone應用程序,並在StoryBoard中的詳細視圖(最好是上半部分的某個地方)添加一個文本字段,運行應用程序,添加項目,就可以輕松復制問題。 ,點擊它以轉到詳細視圖並單擊您添加的文本字段。 從設備左側邊緣滑動,同時將手指放在上面,您將看到問題。

期望的行為:

期望的行為

目前的行為:

鍵盤撕裂

不幸的是,沒有內置的方法來做到這一點。 我真的希望UIScrollViewKeyboardDismissModeInteractive用於UIViewController

目前,要在viewControllers之間執行任何動畫,您應該使用transitionCoordinator

- (BOOL)animateAlongsideTransition:(void (^)(id <UIViewControllerTransitionCoordinatorContext>context))animation
                        completion:(void (^)(id <UIViewControllerTransitionCoordinatorContext>context))completion;

- (BOOL)animateAlongsideTransitionInView:(UIView *)view
                               animation:(void (^)(id <UIViewControllerTransitionCoordinatorContext>context))animation
                              completion:(void (^)(id <UIViewControllerTransitionCoordinatorContext>context))completion;

對於鍵盤,你應該這樣做:

[self.transitionCoordinator animateAlongsideTransitionInView:self.keyboardSuperview
                                                   animation:
^(id<UIViewControllerTransitionCoordinatorContext> context) {
    self.keyboardSuperview.x = self.view.width;
}
                                                  completion:nil];

至於keyboardSuperview - 你可以通過創建一個假的inputAccessoryView來獲得它:

self.textField.inputAccessoryView = [[UIView alloc] init];

然后superview將是self.textField.inputAccessoryView.superview

它應該自動工作,但有時它不會因為某些條件。

如果當前的firstResponder位於活動的UIViewController內部並且它在整個UINavigationController機制中被解除,則將自動執行預期的鍵盤動畫(水平)。 因此,有時這種默認行為會被其他奇怪的因素打破,鍵盤開始消失,而不是水平動畫。

我花了幾天時間調試內部UIKit的東西(圍繞方法needDeferredTransitionallowCustomTransition和其他)找到一個在我的情況下起關鍵作用的特殊因素。

我發現內部的邏輯UIPeripheralHost檢查frame電流UIViewConroller的視圖, frameUINavigationController的視圖(容器)和屏幕size ,並且如果所有不等於彼此, UIPeripheralHost決定這一現狀似乎像模態窗口並設置標志allowCustomTransition = NO 關閉UINavigationController特定的水平動畫。

修復frame s的問題完全解決了我的問題。

如果您遇到相同的問題,可以嘗試圍繞這些私有方法調試內部UIKit的東西,並找到關閉水平動畫的條件:

https://github.com/JaviSoto/iOS8-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UIPeripheralHost.h

https://github.com/JaviSoto/iOS8-Runtime-Headers/blob/master/Frameworks/UIKit.framework/_UIViewControllerKeyboardAnimationStyle.h

如果您不需要任何特殊功能,可以使用https://github.com/cotap/TAPKeyboardPop

在我的情況下,我有一些邏輯與UIKeyboardWillShowNotificationUIKeyboardWillHideNotification ,這些邏輯是在“向后滑動”手勢上觸發的。 我把這個答案TAPKeyboardPop結合起來,這就是我所擁有的:

- (void)beginAppearanceTransition:(BOOL)isAppearing animated:(BOOL)animated {
    [super beginAppearanceTransition:isAppearing animated:animated];
    if (isAppearing || !animated || !_keyboardIsShown) {
        return;
    }
    if ([self respondsToSelector:@selector(transitionCoordinator)]) {
        UIView *keyboardView = self.searchBar.inputAccessoryView.superview;
        [self.searchBar becomeFirstResponder];
        [self.transitionCoordinator animateAlongsideTransitionInView:keyboardView
                                                           animation:^(id<UIViewControllerTransitionCoordinatorContext> context)
         {
             CGRect endFrame = CGRectOffset(keyboardView.frame, CGRectGetWidth(keyboardView.frame), 0);
             keyboardView.frame = endFrame;
         } completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
         {
             if (![context isCancelled]) {
                 [self.searchBar resignFirstResponder];
             }
         }];
    }
}

編輯:

我已經添加了> iOS7支持和邏輯,用於了解何時顯示鍵盤( _keyboardIsShownUIKeyboardWillShowNotification/UIKeyboardWillHideNotificationUIKeyboardDidHideNotification/UIKeyboardDidShowNotification )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM