前言
??近期參與了一個(gè)招聘類app的開發(fā)淆攻,注冊(cè)流程比較多,基本都是cell帶輸入框的表單列表樣式嘿架,避免不了的就會(huì)遇到鍵盤遮擋問題瓶珊。相信大家也一定遇到過類似的問題,今天在這里就給大家分享一下耸彪,這個(gè)問題的解決思路伞芹。
實(shí)現(xiàn)方案
??我們先來分析一下這個(gè)需求,首先蝉娜,這個(gè)表單是一個(gè)列表list(UITableView或者UICollectionView)唱较,如圖1所示,當(dāng)用戶點(diǎn)擊輸入框1召川、2南缓、3、4荧呐、5的時(shí)候汉形,彈出鍵盤但不會(huì)被遮擋,這種情況倍阐,不用做處理概疆,當(dāng)用戶點(diǎn)擊輸入框6、7峰搪、8岔冀,彈出鍵盤會(huì)遮擋輸入框,想要讓輸入框顯示出來概耻,我們有兩個(gè)辦法使套,第一可以向上修改整個(gè)列表view的frame的y值,第二可以修改列表的contentoffset的y值咐蚯,都可以達(dá)到效果童漩,下邊我們選擇第二種方式來實(shí)現(xiàn)我們的需求。
具體實(shí)現(xiàn)分以下幾步:
- 監(jiān)聽鍵盤彈起和收起事件
- 計(jì)算鍵盤高度
- 計(jì)算contentoffset的y值要改變的差值并修改contentoffset的值
- 滑動(dòng)列表時(shí)收起鍵盤
- 鍵盤收起時(shí)還原contentoffset的值
下面一起來通過代碼實(shí)現(xiàn)這個(gè)5步
第一步__設(shè)置監(jiān)聽
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardAction:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardAction:) name:UIKeyboardWillHideNotification object:nil];
第二步__計(jì)算高度
// 鍵盤監(jiān)聽事件
- (void)keyboardAction:(NSNotification*)sender{
NSDictionary *useInfo = [sender userInfo];
NSValue *value = [useInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
//鍵盤高度
CGFloat height = [value CGRectValue].size.height;
if ([sender.name isEqualToString:UIKeyboardWillShowNotification]) {
//鍵盤彈起時(shí)
} else {
//鍵盤收起時(shí)
}
}
第三步__計(jì)算contentoffset的y值要改變的差值并修改contentoffset的值
??我們以點(diǎn)擊第7個(gè)輸入框?yàn)槔悍妫?dāng)點(diǎn)擊第7個(gè)輸入框的時(shí)候矫膨,我們想要的效果是讓第7個(gè)輸入框跑到鍵盤上邊,如圖2所示
??那么這里我們就要計(jì)算一下需要向上移動(dòng)的距離delta=3-(2-1),2是list的高度侧馅,1是鍵盤的高度危尿,3是第7個(gè)輸入框所在cell的maxY值-當(dāng)前l(fā)ist的contentoffset的y值,如圖3馁痴,
??1和2我們很好獲得谊娇,重點(diǎn)是獲取3的值,我們只要獲取到第7個(gè)輸入框所在cell的實(shí)例罗晕,然后通過CGRectGetMaxY(cell.frame)即可獲得此值济欢。下邊是獲取到cell實(shí)例的代碼
- (UICollectionViewCell *)firstResponderCell {
__block UICollectionViewCell *cell = nil;
[self.collectionView.visibleCells enumerateObjectsUsingBlock:^(__kindof UICollectionViewCell * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
UICollectionViewCell *visibleCell = obj;
//焦點(diǎn)所在的textField
if (visibleCell.textField.isFirstResponder) {
cell = visibleCell;
}
}];
return cell;
}
??計(jì)算差值改變contentoffset
// 鍵盤監(jiān)聽事件
- (void)keyboardAction:(NSNotification*)sender{
NSDictionary *useInfo = [sender userInfo];
NSValue *value = [useInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
//鍵盤高度
CGFloat keyboardHeight = [value CGRectValue].size.height;
//列表的高度
CGFloat collectionViewHeight = self.collectionView.frame.size.height;
if ([sender.name isEqualToString:UIKeyboardWillShowNotification]) {
//鍵盤彈出時(shí)
//獲取輸入框焦點(diǎn)所在的cell
UICollectionViewCell *cell = [self firstResponderCell];
if (cell) {
//cell的maxY值
CGFloat cellMaxY = CGRectGetMaxY(cell.frame)- self.collectionView.contentOffset.y;
//差值 = 3 -(2-1)
if (cellMaxY > collectionViewHeight-keyboardHeight) {
//記錄delta值,鍵盤收起恢復(fù)原來位置時(shí)使用
self.delta = cellMaxY-(collectionViewHeight-keyboardHeight);
self.collectionView.contentOffset = CGPointMake(0, self.collectionView.contentOffset.y+self.delta);
}
}
} else {
//鍵盤收起時(shí)
}
}
第四步__滑動(dòng)列表時(shí)收起鍵盤
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
UICollectionViewCell *cell = [self firstResponderCell];
if (cell) {
[cell.textField resignFirstResponder];
}
}
第五步__鍵盤收起時(shí)還原contentoffset的值
// 鍵盤監(jiān)聽事件
- (void)keyboardAction:(NSNotification*)sender{
NSDictionary *useInfo = [sender userInfo];
NSValue *value = [useInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
//鍵盤高度
CGFloat keyboardHeight = [value CGRectValue].size.height;
//列表的高度
CGFloat collectionViewHeight = self.collectionView.frame.size.height;
if ([sender.name isEqualToString:UIKeyboardWillShowNotification]) {
//鍵盤出現(xiàn)時(shí)
} else {
//鍵盤收起時(shí)
//根據(jù)self.delta復(fù)原
self.collectionView.contentOffset = CGPointMake(0, self.collectionView.contentOffset.y-self.delta);
self.delta = 0
}
}
實(shí)現(xiàn)完畢小渊,怎么樣法褥,是不是很簡(jiǎn)單~~~~~