使用通知中心監(jiān)聽(tīng)事件
在qq中,用戶點(diǎn)擊鍵盤(pán)時(shí),鍵盤(pán)彈出,聊天框也會(huì)隨之移動(dòng).基本的思路是,當(dāng)監(jiān)聽(tīng)到鍵盤(pán)彈出時(shí),需要將tableView上移一個(gè)鍵盤(pán)的高度,當(dāng)用戶滾動(dòng)tableView時(shí),將鍵盤(pán)收起,同時(shí)還原tableView至屏幕底部.要修改tableView的高度,需要取消tableview的頂部約束,固定tableview的高度約束即可.
tableView的約束


1.在storyboard底部搭建聊天欄底部界面,并設(shè)置相應(yīng)的約束.

其中的層級(jí)結(jié)構(gòu)如下:

2.將狀態(tài)欄view的底部與控制器的view底部那根約束拖線只控制器文件中,當(dāng)控制器監(jiān)聽(tīng)到鍵盤(pán)彈出或收起時(shí),只需修改constant值即可.如下圖所示:

3.控制器要監(jiān)聽(tīng)鍵盤(pán)的狀態(tài),需要拿到textFeild對(duì)象,在鍵盤(pán)狀態(tài)改變時(shí),系統(tǒng)會(huì)發(fā)送通知,接收通知并調(diào)用相應(yīng)的方法即可.將textFeild拖線值控制器.
@property (weak, nonatomic) IBOutlet UITextField *messageFeild;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
//設(shè)置textFeild的光標(biāo)向后移動(dòng)5個(gè)像素的距離
UIView *leftView = [[UIView alloc] init];
leftView.frame = CGRectMake(0, 0, 5, 0);
self.messageFeild.leftView = leftView;
self.messageFeild.leftViewMode = UITextFieldViewModeAlways;
//添加一個(gè)通知,當(dāng)keyboard的frame改變時(shí)就會(huì)調(diào)用keyboardChangeFrame:方法
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
}
4 .實(shí)現(xiàn)keyboardChangeFrame:方法
- (void)keyboardChangeFrame:(NSNotification *)note{
//取出note.userInfo中鍵盤(pán)所改變的frame
CGRect value = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
//取出note.userInfo中鍵盤(pán)彈出所需要的時(shí)間
double duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[UIView animateWithDuration:duration animations:^{
//設(shè)置約束的值為控制器的高度減去鍵盤(pán)改變的值(鍵盤(pán)彈出時(shí)y值減少,收起是y值為控制器的高度)
self.buttomSpacing.constant = self.view.frame.size.height - value.origin.y;
}];
//強(qiáng)制布局子控件,實(shí)現(xiàn)動(dòng)畫(huà)效果
[self.view layoutIfNeeded];
5.設(shè)置鍵盤(pán)收起
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
[self.messageFeild resignFirstResponder];
}
6.使用NSNotificationCenter時(shí)必須重寫(xiě)dealloc方法移除觀察者,否則當(dāng)觀察者釋放之后再訪問(wèn)會(huì)造成程序崩潰.
- (void)dealloc{
//使用NSNotificationCenter時(shí)必須重寫(xiě)dealloc方法移除觀察者,否則當(dāng)觀察者釋放之后再訪問(wèn)會(huì)造成程序崩潰
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
使用transform修改約束
只需將修改約束的代碼修改為:
- (void)keyboardWillChangeFrame:(NSNotification *)note {
// 取出鍵盤(pán)最終的frame
CGRect rect = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
// 取出鍵盤(pán)彈出需要花費(fèi)的時(shí)間
double duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
// 修改transform
[UIView animateWithDuration:duration animations:^{
CGFloat ty = [UIScreen mainScreen].bounds.size.height - rect.origin.y;
self.view.transform = CGAffineTransformMakeTranslation(0, - ty);
}];
}