9.27更新:
新項目中重新對鍵盤彈出的效果進行了封裝,只需要三步就可以完成相關操作,并且支持TextView了。
添加觀察者
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addKeyboardNotification];
}
隱藏鍵盤操作
[[self.view getIsEditingText] resignFirstResponder];
移除觀察者
- (void)dealloc {
[self.view removeKeyboardNotification];
}
正文:
之前項目中遇到鍵盤彈出遮擋輸入框時, 都是使用三方庫DaiDodgeKeyboard
進行界面上移動畫, 這個三方庫很方便, 但是有時候會出現如tableview.tableFooterView
變短、大屏適配失效等非常詭異的情況, 所以本狼參考著網上資料自己動手實現了一個簡單的效果.
- 添加一下鍵盤的通知, 并記得移除
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
- 寫一個方法取到編輯狀態下的
textfield
- (void)getIsEditingView:(UIView *)rootView {
for (UIView *subView in rootView.subviews) {
if ([subView isKindOfClass:[UITextField class]]) {
if (((UITextField *)subView).isEditing) {
self.editingTextField = subView;
return;
}
}
[self getIsEditingView:subView];
}
}
- 計算已經拿到的
textfield
在屏幕中的位置
- (CGFloat)screenViewYValue:(UIView *)textfield {
CGFloat y = 0;
for (UIView *view = textfield; view; view = view.superview) {
y += view.frame.origin.y;
if ([view isKindOfClass:[UIScrollView class]]) {
// 如果父視圖是UIScrollView則要去掉內容滾動的距離
UIScrollView* scrollView = (UIScrollView*)view;
y -= scrollView.contentOffset.y;
}
}
return y;
}
因為我們不可能凡是textfield
就上移, 所以要拿到位置再進行判斷.
- 最后針對拿到的這個位置來進行視圖上移處理, 也就是通知執行的方法
- (void)keyboardWillShow:(NSNotification *)noti {
// 拿到正在編輯中的textfield
[self getIsEditingView:self.view];
// textfield的位置
CGFloat viewY = [self screenViewYValue:self.editingTextField];
// 鍵盤的Y值
NSDictionary *userInfo = [noti userInfo];
NSValue *value = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGFloat keyboardEndY = value.CGRectValue.origin.y;
// 動畫
NSNumber *duration = [userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
[UIView animateWithDuration:duration.doubleValue animations:^{
if (viewY+30 > keyboardEndY) {
CGRect rect = self.tableView.frame;
rect.origin.y += keyboardEndY - (viewY+30);
self.tableView.frame = rect;
}
}];
}
- 鍵盤收起方法就比較簡單了, 直接復位即可
- (void)keyboardWillHide:(NSNotification *)noti {
CGRect rect = self.tableView.frame;
rect.origin.y = 0;
self.tableView.frame = rect;
}
至此就基本實現了鍵盤彈出的動畫效果, 可能還要具體需求具體分析, 不過一般場景已經夠用, 其中-(CGFloat)screenViewYValue:
方法是一個系列的, 本狼是寫在UIView
的類別里, 這里為了方便展示就單獨拿了出來, 建議還是將方法整理寫到類別中.
關注豺狼的訂閱號, 更新的新文章會第一時間收到通知~