iOS tableview鍵盤遮擋問題

這個問題很常見,相信大家也遇到過,網上的解決辦法也一大堆。下面說說我遇到的問題,在此記錄一下。

1.如果是普通的頁面,是指在controller上直接鋪控件UITextField(比如登錄、註冊頁等),要求不是很高的可以選擇在鍵盤彈出時,view整體上移(不管鍵盤是否遮擋),代碼如下:

RegisterViewController.m

 

@interface RegisterViewController ()<UITextViewDelegate>

{

    CGFloat keyboardHeight;//記錄鍵盤的高度

}

@property (nonatomic) CGRect viewFrame; //記錄當前view的frame

@end

 

@implementation RegisterViewController

- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view.

    self.viewFrame = self.view.frame;//注意這一句,要先記錄一下頁面frame並賦值

    [self addNotification];//註冊鍵盤彈出、消失的通知

}

-(void)addNotification

{

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

}

//鍵盤彈出的時候

-(void)keyboardWillShow:(NSNotification *)notificaiton

{

    CGRect keyboardFrame = [[notificaiton.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];

    keyboardHeight = keyboardFrame.size.height;

   CGPoint point = self.view.center;

    point.y -= 120;//120是根據你實際的需求,不一定是多少

    [UIView animateWithDuration:0.3f animations:^{

        self.view.center = point;

    }];

}

//鍵盤消失的時候,回覆原來的frame

-(void)keyboardWillHide:(NSNotification *)notificaiton

{

    self.view.frame = self.viewFrame;

}

//養成好習慣移除通知

- (void)dealloc{

    //移除鍵盤通知監聽者

    [[NSNotificationCenter defaultCenter]removeObserver:self name:UIKeyboardWillShowNotification object:nil];

    [[NSNotificationCenter defaultCenter]removeObserver:self name:UIKeyboardWillHideNotification object:nil];

}

@end

 

2.下面這種情況是本文說的重點,也非常常見。大家肯定經常會用到tableview頁面,然後在tableviewCell裏面有UITextField控件,這時候也肯定會遇到遮擋的問題,大家首先想法就是UITextField輸入完之後就回收鍵盤(可以點擊空白處回收鍵盤),這樣的話體驗不太好,造成用戶看不到正在給哪一個UITextField輸入內容。思路:你的控件(也就是UITextField相對於最外層view的位置(y座標)跟彈出鍵盤相對於最外層view的位置(y座標),相比較,看是否遮擋),如果遮擋了計算出遮擋的高度,然後設置最外層視圖的frame,往上移動到大於等於遮擋遮住的高度即可。下面就是解決辦法,不多說,直接上代碼,如下:

 

首先TableViewCell.h

typedef void (^CellTextFieldValueChangedBlock)(UITextField *tf);//爲什麼參數有UITextField 下面在controller會有講解,該block是爲了textField回調用

@interface TableViewCell : UITableViewCell<UITextFieldDelegate>

@property(nonatomic,strong)UITextField *contentField;

@property(nonatomic,copy)CellTextFieldValueChangedBlock block;

-(void)cellFieldBlock:(CellTextFieldValueChangedBlock)block;

TableViewCell.m

在你創建textFiled的時候,給textField加上點擊事件

[self.contentField addTarget:self action:@selector(textField:) forControlEvents:UIControlEventEditingDidBegin];//注意是UIControlEventEditingDidBegin,至於爲什麼就不講解了

 

//下面就是一個簡單的block回傳

-(void)textField:(UITextField *)textField{

    if (self.block) {

        self.block(textField);

    }

}

-(void)cellFieldBlock:(CellTextFieldValueChangedBlock)block{

    self.block = block;

}

接下來到我們的controller了,

@interface InfoViewController ()<UITableViewDelegate, UITableViewDataSource,UIGestureRecognizerDelegate,UITextFieldDelegate>

@property(nonatomic ,strong) UITextField * firstResponderTextF;//記錄將要編輯的輸入框,從cell裏傳過來的UITextField就用到了

@end

@implementation InfoViewController

//省略其他代碼直接看重點,tableview的代理方法

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

    static NSString *cellIdentifier = @"ResetCell";

    NSInteger section = indexPath.section;

    NSInteger row = indexPath.row;

    TableViewCell *cell = (TableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (cell == nil) {

        cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];

    }

    cell.contentField.delegate = self;

    WEAK_SELF(weakSelf)

    [cell cellFieldBlock:^(UITextField * _Nonnull tf) {

        weakSelf.firstResponderTextF = tf;//記錄編輯的textField,稍後再鍵盤彈出的方法裏有用

        [weakSelf addNotification];//同樣註冊鍵盤彈出、消失的通知,這裏爲什麼在回調裏註冊相信你試一下就知道了

    }];

    return cell;

}

 

#pragma mark : UIKeyboardWillShowNotification/UIKeyboardWillHideNotification

- (void)keyboardWillShow:(NSNotification *)notification{

    CGRect rect = [self.firstResponderTextF.superview convertRect:self.firstResponderTextF.frame toView:self.tableView];//獲取當前輸入的textField相對於self.tableView的位置

 //會有人問爲什麼是tableview而不是view,因爲tableview是最外層,你的textField也是加在tableview上

  CGRect keyboardRect = [[notificaiton.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];//獲取鍵盤高度

    keyboardRect = [self.tableView convertRect:keyboardRect fromView:nil];//獲取鍵盤相對於self.tableView的frame 

    CGFloat keyboardTop = keyboardRect.origin.y;//用於跟textField的y比較

    NSNumber * animationDurationValue = [userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];//獲取鍵盤彈出動畫時間值

    NSTimeInterval animationDuration = [animationDurationValue doubleValue];

    if (keyboardTop < CGRectGetMaxY(rect)) {//如果鍵盤蓋住了輸入框

        CGFloat gap = keyboardTop - CGRectGetMaxY(rect) - 10;//計算需要往上移動的偏移量(輸入框底部離鍵盤頂部爲10的間距)

        WEAK_SELF(weakSelf)

        [UIView animateWithDuration:animationDuration animations:^{

            weakSelf.tableView.frame = CGRectMake(weakSelf.tableView.frame.origin.x, gap, weakSelf.tableView.frame.size.width, weakSelf.tableView.frame.size.height);

        }];

    }

}

- (void)keyboardWillHide:(NSNotification *)notification{

    NSDictionary *userInfo = [notification userInfo];

    NSNumber * animationDurationValue = [userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];//獲取鍵盤隱藏動畫時間值

    NSTimeInterval animationDuration = [animationDurationValue doubleValue];

    if (self.tableView.frame.origin.y < 0) {//如果有偏移,當影藏鍵盤的時候就復原

        WEAK_SELF(weakSelf)

        [UIView animateWithDuration:animationDuration animations:^{

            weakSelf.tableView.frame = CGRectMake(weakSelf.tableView.frame.origin.x, 0, weakSelf.tableView.frame.size.width, weakSelf.tableView.frame.size.height);

        }];

    }

}

-(void)addNotification

{

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

}

@end

上面就是遇到問題的解決辦法,在此記錄一下,同時鞏固一下便於以後使用。

另附上,tableview點擊空白處回收鍵盤代碼,如下:

在controller裏初始化的時候 ,一般都在viewDidLoad方法

 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGesturedAction:)];

    tap.delegate = self;//注意代理

    [self.tableView addGestureRecognizer:tap];

#pragma mark -UIGestureRecognizer

-(void)tapGesturedAction:(UIGestureRecognizer *)gesture{

   [self.tableView endEditing:YES];

}

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {

    NSLog(@"-----%@",NSStringFromClass([touch.view class]));

  //如果某些地方不希望回收鍵盤,可以用NSStringFromClass([touch.view class])來處理,具體需求具體分析

    return YES;

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章