iOS中表單列表樣式鍵盤遮擋的解決方案
前言
近期參與了一個(gè)招聘類app的開發(fā),注冊(cè)流程比較多,基本都是cell帶輸入框的表單列表樣式,避免不了的就會(huì)遇到鍵盤遮擋問題。相信大家也一定遇到過類似的問題,今天在這里就給大家分享一下,這個(gè)問題的解決思路。
實(shí)現(xiàn)方案
我們先來(lái)分析一下這個(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ì)遮擋輸入框,想要讓輸入框顯示出來(lái),我們有兩個(gè)辦法,第一可以向上修改整個(gè)列表view的frame的y值,第二可以修改列表的contentoffset的y值,都可以達(dá)到效果,下邊我們選擇第二種方式來(lái)實(shí)現(xiàn)我們的需求。
具體實(shí)現(xiàn)分以下幾步:
- 監(jiān)聽鍵盤彈起和收起事件
- 計(jì)算鍵盤高度
- 計(jì)算contentoffset的y值要改變的差值并修改contentoffset的值
- 滑動(dòng)列表時(shí)收起鍵盤
- 鍵盤收起時(shí)還原contentoffset的值
圖1
下面一起來(lái)通過代碼實(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所示
圖2
那么這里我們就要計(jì)算一下需要向上移動(dòng)的距離delta=3-(2-1),2是list的高度,1是鍵盤的高度,3是第7個(gè)輸入框所在cell的maxY值-當(dāng)前l(fā)ist的contentoffset的y值,如圖3,
圖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ù)原來(lái)位置時(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)單~~~~~
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
iOS保存App中的照片到系統(tǒng)相冊(cè)或自建相冊(cè)的方法
這篇文章主要介紹了iOS保存App中的照片到系統(tǒng)相冊(cè)或自建相冊(cè)的方法,示例代碼為傳統(tǒng)的Objective-C語(yǔ)言寫成,需要的朋友可以參考下2016-04-04詳解Swift中對(duì)C語(yǔ)言接口緩存的使用以及數(shù)組與字符串轉(zhuǎn)為指針類型的方法
這篇文章主要介紹了詳解Swift中對(duì)C語(yǔ)言接口緩存的使用以及數(shù)組與字符串轉(zhuǎn)為指針類型的方法的相關(guān)資料,這里提供簡(jiǎn)單實(shí)例,代碼注釋介紹也清楚,需要的朋友可以參考下2017-07-07iOS應(yīng)用開發(fā)中使用設(shè)計(jì)模式中的觀察者模式的實(shí)例
這篇文章主要介紹了iOS應(yīng)用開發(fā)中使用設(shè)計(jì)模式中的觀察者模式的實(shí)例,包括Cocoa框架使用中的KVO機(jī)制的相關(guān)配合運(yùn)用,代碼為傳統(tǒng)的Objective-C,需要的朋友可以參考下2016-03-03iOS如何用100行代碼實(shí)現(xiàn)簡(jiǎn)單的抽屜效果
最近在網(wǎng)上看到一些抽屜效果,看起來(lái)很酷!很眩!但是,下不下來(lái)看代碼, 所以決定還是自己寫吧!!這篇文章通過近100行的代碼就實(shí)現(xiàn)了簡(jiǎn)單的抽屜效果,有需要的朋友們可以參考借鑒,下面來(lái)一起看看吧。2016-10-10總結(jié)iOS實(shí)現(xiàn)漸變顏色的三種方法
這篇文章主要給大家總結(jié)了iOS實(shí)現(xiàn)漸變顏色的三種方法,分別是利用CAGradientLayer實(shí)現(xiàn)漸變、Core Graphics相關(guān)方法實(shí)現(xiàn)漸變以及用CAShapeLayer作為layer的mask屬性實(shí)現(xiàn),大家可以根據(jù)自己的需要選擇使用,下面來(lái)一起看看吧。2016-10-10