1. 程式人生 > >ios鍵盤彈出擋住帶自定義UITableViewCell的UITableView的解決方法

ios鍵盤彈出擋住帶自定義UITableViewCell的UITableView的解決方法

案例:

需要做一個UITableView,其包含兩個section,其中一個section中的cell是UITableViewCell類物件,另一個section中的cell是自定義的Cell類物件,自定義的Cell是一個表單,裡面包含有多個UITextField。

遇到的問題:

當我點選的UITextField,系統彈出鍵盤的時候,所有的UITextField控制元件都被彈出的鍵盤擋住了。

解決思路:

在點選了UITextField控制元件,彈出鍵盤的時候,把整個tableView向上移動一段距離,等結束輸入之後,就把整個tableView移動回來

步驟:

1.捕獲點中UITextField控制元件的事件

因為我的控制元件是在自定義的UITableViewCell中的,所以,我在自定義的UITableViewCell字類,假設是ACell中定義了一個方法-(IBAction)beginEditting:(id)sender,用於相應點中UITextField控制元件事件,因為點中UITextField事件會發出EditingDidBegin事件,所以根據這個事件連線上上述定義的方法,那麼在點中UITextField控制元件的時候,就會自動呼叫上述的方法。

2.移動tableView

這時問題是,在方法中,我們怎麼能控制到tableView移動呢?因為當前程式碼是在自定義類中編寫的,無法直接呼叫到tableView物件。我們可以通過獲取上級View的辦法來獲取到包含這個自定義cell的TableView,也就時superView,一個View呼叫superView方法,就能夠獲取到包含自身的View的物件。但是這裡要注意,因為UITextField自己本身也是一個View,所以要獲取到tableView,我們需要執行textField.superView.superView,因為第一個superView得到的時包含了這個UITextField的Cell,再呼叫superView,才得到包含這個Cell得TableView。

獲取到tableView物件後,想對它進行移動就很容易了,只要獲取到tableView得frame,然後改變它origin得x,y值,然後修改好之後再賦值回去,就可以移動它的位置了。

3.動畫移動tableView

移動tableView可能很容易就可以實現,但是總會令人覺得不舒服,因為在鍵盤彈出的時候,tableView閃一下就移動到指定的位置中去了,非常不美觀。所以這裡用動了動畫的方式,讓tableView滑動到指定的地方,這裡的動畫也很簡單,就三句程式碼,由於本人還沒認真去了解動畫,所以在此就不求甚解了。使用動畫滑動的程式碼如下:

    [UIView beginAnimations:@"moveView" context:nil];
    [UIView setAnimationDuration:0.3];//移動的速度
    parentView.frame = frame;//移動後的位置,其他修改也是寫到這個位置
    [UIView commitAnimations];

-(IBAction)beginEditting:(id)sender的完整實現如下:
- (void)beginEditting:(id)sender
{
    
    UIView *parentView = self.superview.superview;
    CGRect frame = parentView.frame;
    frame.origin.y -= frame.size.height*0.3;
    [UIView beginAnimations:@"moveView" context:nil];
    [UIView setAnimationDuration:0.3];
    parentView.frame = frame;
    [UIView commitAnimations];
}

在自定義UITableViewCell類中寫好這個方法,並在Interface Builder中連好線,就可以實現點選自定義UITableViewCell,鍵盤彈出來的時候,tableView會向上滑動一段距離了。

4.輸入完畢,點選非UITextField類的控制元件時,鍵盤退回,tableView滑回原本的位置

這時想到的方法就是給當前的view新增一個點選的手勢tap(網上有人說要用tableView的background來處理手勢,其實過程一樣,等下會解釋),當用戶tap了一下view的時候,就退回鍵盤,並把tableView移動回原來的位置,所以自定義了一個手勢,方法如下:

    UITapGestureRecognizer *tap = [[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapOnce)]autorelease];
    [tap setNumberOfTapsRequired:1];
    tap.delegate = self;
    [self.view addGestureRecognizer:tap];
而點選的響應方法如下:
- (void)tapOnce
{
    CGRect frame = self.costFormTableView.frame;
    if (frame.origin.y == 0) {     //防止view在正常狀態下也被移動
        return ;
    }
    frame.origin.y += frame.size.height*0.3;
    [UIView beginAnimations:@"moveView" context:nil];
    [UIView setAnimationDuration:0.3];
    self.costFormTableView.frame = frame;
    [UIView commitAnimations];
}
這時,點選的tableView,可以捕獲到tap事件,自己的在相應的響應方法內列印一些資訊出來判斷,但是,tableView被來含有的一些cell點選後就沒有反應了。

5.解決點中tableViewCell,點選事件被手勢事件截獲的現象。

本人測試過,如上面所說,就算事給tableView的background新增手勢,也一樣會遮蔽掉tableViewCell的點選響應,所以解決的辦法,是判斷點選到的控制元件的型別,如果點中的控制元件的型別是tableViewCell的話,就讓自定義的手勢不生效。這時就要在使當前類實現UIGestureRecognizerDelegate協議,然後重寫一下方法:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    NSLog(@"%@",NSStringFromClass(touch.view.class)); //可以用這個方法來判斷自己點中的控制元件使什麼型別,然後用下面的if語句處理
    if ([NSStringFromClass(touch.view.class) isEqualToString:@"UITableViewCellContentView"])
    {
        if (self.costFormTableView.frame.origin.y != 0) {  //這裡使防止tableView上移後,螢幕上的內容剛好之後Cell和鍵盤,這樣點選Cell中的非UITextField控制元件一樣可以使tableView移動回原來的位置
            return YES;
        }
        return NO;
    }
    return YES;
}

這時,點中tableViewcell物件的時候,就能響應其原來的事件而不會被自定義的tap手勢遮蔽掉了。

6.最後一個問題,當tableView移動到原本的位置的時候,鍵盤還保留在頁面上。

使鍵盤退回的方法,網上提到的都是用控制元件呼叫resignFirstResponder的方法,但是在這個案例中,感覺有點麻煩,被人也試過使用這種方法,但是不知道使操作錯誤還是其他原因,都無法實現。但是在一次無意的嘗試中,發現呼叫tableView的reloadData時,鍵盤迴退回,所以修改上述的手勢響應方法,如下:

- (void)tapOnce
{
    CGRect frame = self.costFormTableView.frame;
    if (frame.origin.y == 0) {
        return ;
    }
    frame.origin.y += frame.size.height*0.425;
    [UIView beginAnimations:@"moveView" context:nil];
    [UIView setAnimationDuration:0.3];
    self.costFormTableView.frame = frame;
    [self.costFormTableView reloadData];   //加上這一句
    [UIView commitAnimations];
}

估計時因為reloadData的時候,tableView中的控制元件都會重新載入資料,在此同時所有控制元件都失去了firstResponder,所以鍵盤就自動退回去了。

到此,這個案例就完成了。


相關推薦

ios鍵盤擋住定義UITableViewCell的UITableView的解決方法

案例: 需要做一個UITableView,其包含兩個section,其中一個section中的cell是UITableViewCell類物件,另一個section中的cell是自定義的Cell類物件,自定義的Cell是一個表單,裡面包含有多個UITextField。 遇

android定義dialog,軟體鍵盤擋住輸入區域解決

在做新浪oauth2.0認證時,裡面有一個自定義dialog的類。dialog中載入的是一一個webview。當鍵盤彈起的時候就會彈住輸入區域。 解決辦法: 在dialog的oncarete方法中加  getWindow().setSoftInputMode(WindowManager.LayoutPara

iOS鍵盤的時候會擋住底部的控制元件,可以通過以下方法將整個UIView上移。

//通知中心addObserver [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(transformView:) name:UIKeyboardWillChangeFr

Swift 版本: 2.利用 NSNotificationCenter實現鍵盤時頁面適應

在前面的一個小 Demo 裡, 我們知道了怎麼用UISearchController實現一個本地的搜素引擎, 現在讓我們繼續來看看接下來的Demo. 1.介面佈局 使用自動佈局給UI控制元件進行約束 獲取Bottom屬性 2.程式碼實現 獲取Bottom屬性

android 小米手機框(定義dialog)位置不居中解決方法

在建立dialog或者構造方法出加入如下程式碼就可以解決問題、 Window window = dialog.getWindow(); if (dialog != null &a

layer層擴充套件定義樣式

layer是一款近年來備受青睞的web彈層元件,她具備全方位的解決方案,致力於服務各水平段的開發人員,您的頁面會輕鬆地擁有豐富友好的操作體驗。 官網 http://layer.layui.com/ layer 擴充套件面板:  http://layer.la

layer 框與定義樣式

1 匯入layer.js2 匯入自定義的layer.css @charset "utf-8";body .p_window {border: none; font-size: 12px; font-family: "Microsoft Yahei", sans-serif;}

iOS 鍵盤與回收、介面上移和下移

//新增通知,來控制鍵盤和輸入框的位置     [[NSNotificationCenterdefaultCenter] addObserver:selfselector:@selector(ke

iOS鍵盤完美移動控制元件

新增監聽(最好放在ViewWillAppear裡, 在檢視將要消失時移除監聽) 這裡監聽鍵盤Frame的變化而不是監聽鍵盤的顯示和隱藏 [[NSNotificationCenter defaultCe

iOS鍵盤與退回和文字框的完美適配

如上圖所示,需要編輯使用者的資訊,鍵盤需要根據所輸入的行來合理的顯示鍵盤位置 ①,文字框新增監聽 //新增監聽   [selfaddRegisterText:leftTitleRightText.textFieldRight]; //新增監聽 - (void)add

Android安卓WebApp中 全屏和普通模式下 webview中軟鍵盤擋住輸入框 解決方案

最近公司開發的WEBAPP遇到了一個比較噁心的問題。就是在webview中當需要輸入內容時,軟鍵盤彈起後,擋住了輸入框,試了很多辦法都不太滿意。(這裡要吐槽下,人家IOS端,蘋果系統都給直接封裝好了,

Android軟鍵盤,介面整體上移終極解決方式

今天在應測試要求:軟鍵盤彈出不能遮擋EditView,在網上找了各種方案,基本都不行,比如: android:windowSoftInputMode=“adjustResize|stateHidden” 可能在一般的頁面是可以用吧。 下面來說一個曲線救國的方案,

h5頁面 在安卓手機端軟鍵盤頂起頁面佈局的解決辦法

var oHeight = $(document).height();     $(window).resize(function(){ //ios軟鍵盤彈出不會觸發resize事件         if($(document).height() < oHeight){             $("#

ionic開發中,鍵盤遮擋div內元素的解決方案

採用ionic 開發中,遇到鍵盤彈出遮擋元素的問題。 以登陸頁面為例,輸入使用者名稱和密碼時,鍵盤遮擋了登陸按鈕。 最終採用自定義指令解決了問題: .directive('popupKeyBoardShow', [function ($rootScope, $ionicP

關於Pycharm開啟Cannot Lock System Folders的解決方法

彈出這樣的錯誤彈框 解決辦法,管理員命令列下執行指令 netsh winsock reset winsock是Windows網路程式設計介面,winsock工作在應用層,它提供與底層傳輸協議無關的高層資料傳輸程式設計介面 netsh winsock reset

H5禁止手機鍵盤

這個問題,確實困擾了我好久,但是今天解決了。在網上搜索答案,全都是用DIV模擬input框實現,沒有一個真正解決這個問題的,現在我只需要一句程式碼就可以完完整整的解決這個問題。 先看下問題吧: 這個是我自制的一個日曆,在沒有選擇日期前她是這個樣子的,

周記3——解決fixed屬性在ios鍵盤後失效的bug

images fff 發現 apple load http none orien 兩種方法   這周在做空間(“類似”qq空間)項目。首頁是好友發表的說說,可以針對每條說說進行評論,評論框吸附固定在屏幕底部。此時,Bug來了...在ios上,軟鍵盤彈出後fixed屬性失效了

Android定義Toast 解決關閉通知 Toast無法

package common; import android.app.Activity; import android.content.Context; import android.os.Handler; import android.util.Log; import

ios 一步一步學會定義地圖吹框(CalloutView)-->(百度地圖,高德地圖,google地圖)

前言 在ios上邊使用地相簿的同學肯定遇到過這樣的問題:吹出框只能設定title和subtitle和左右的view,不管是百度地圖還是高德地圖還是自帶的google地圖,只提供了這四個屬性,如果想新增更多的view,只能自定義。可是,類庫只能看到.h檔案,.m都看不

h5相容安卓和iOS鍵盤影響佈局的坑

這個是真的坑!!!!!!!!!!!1、先看看正常頁面長什麼樣子,號碼是我亂輸入的,大家不要亂打= =2、然後再看看輸入號碼後鍵盤把這個訂單確認的框頂上去了,頂上去對大螢幕手機也沒關係,就是對小螢幕手機會把訂單確認訂到被隱藏一些。點選鍵盤的下符號後,鍵盤收起來,但是訂單確認這個