对 键盘 事件 监听NSNotification 处理相应页面 变化UIKeyboardAnimation

App应用中,难免会需要用户输入一些相关数据。
于是就用到键盘。
键盘在iPhone和iPad中,类似是一个View的形式来显示和隐藏。
当一个输入框得到焦点时,系统会默认调用键盘事件。来显示键盘;当输入框失去焦点时,键盘会消失。

那么,键盘事件有一下4种:

UIKIT_EXTERN NSString *const UIKeyboardWillShowNotification;

UIKIT_EXTERN NSString *const UIKeyboardDidShowNotification; 

UIKIT_EXTERN NSString *const UIKeyboardWillHideNotification; 

UIKIT_EXTERN NSString *const UIKeyboardDidHideNotification;


1.注册键盘事件:

- (void) viewWillAppear:(BOOL)paramAnimated{

    [super viewDidAppear:paramAnimated];

    

    // 在通知中心注册观察者,并指定观察者感兴趣的事件

    

    // 键盘将要显示时

    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];

    [center addObserver:self

               selector:@selector(handleKeyboardWillShow:)

                   name:UIKeyboardWillShowNotification

                 object:nil];

    

    // 键盘将要隐藏时

    [center addObserver:self

               selector:@selector(handleKeyboardWillHide:)

                   name:UIKeyboardWillHideNotification

                 object:nil];

   

}


2.键盘事件执行的方法:

// 键盘出现时,调用该方法

- (void) handleKeyboardWillShow:(NSNotification *)paramNotification{

    NSDictionary *userInfo = [paramNotification userInfo];

    NSValue *animationCurveObject =[userInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey];

    NSValue *animationDurationObject =[userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey];

    NSValue *keyboardEndRectObject =[userInfo valueForKey:UIKeyboardFrameEndUserInfoKey];

    NSUInteger animationCurve = 0;

    double animationDuration = 0.0f;

    CGRect keyboardEndRect = CGRectMake(0, 0, 0, 0);

    [animationCurveObject getValue:&animationCurve];

    [animationDurationObject getValue:&animationDuration];

    [keyboardEndRectObject getValue:&keyboardEndRect];

    

    [UIView beginAnimations:@"changeTableViewContentInset" context:NULL];

    

    [UIView setAnimationDuration:animationDuration];

    [UIView setAnimationCurve:(UIViewAnimationCurve)animationCurve];

    

    UIWindow *window = [[[UIApplication sharedApplication] delegate] window];// 获得window

    // 得到window.frame和键盘frame的交集

    CGRect intersectionOfKeyboardRectAndWindowRect = CGRectIntersection(window.frame, keyboardEndRect);

    CGFloat bottomInset = intersectionOfKeyboardRectAndWindowRect.size.height;

    self.myTableView.contentInset = UIEdgeInsetsMake(0.0f,0.0f,bottomInset,0.0f);

    NSIndexPath *indexPathOfOwnerCell = nil;

    // 保证得到焦点的UITextField(文本框)也显示在屏幕上

    NSInteger numberOfCells = [self.myTableView.dataSource tableView:self.myTableView

                                               numberOfRowsInSection:0];

    

    // 循环,并且得到获得焦点的UITextField(文本框)所在的UITableViewCell中的NSIndexPath信息,并滚动TableView到相应的位置

    for (NSInteger counter = 0;counter < numberOfCells;counter++){

        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:counter inSection:0];

        UITableViewCell *cell = [self.myTableView cellForRowAtIndexPath:indexPath];

        UITextField *textField = (UITextField *)cell.accessoryView;

        if ([textField isKindOfClass:[UITextField class]] == NO){

            continue;

        }

        if ([textField isFirstResponder]){

            indexPathOfOwnerCell = indexPath;

            break;

        }

    }

    

    [UIView commitAnimations];

    

    // 滚动TableView到相应的位置

    if (indexPathOfOwnerCell != nil){

        [self.myTableView scrollToRowAtIndexPath:indexPathOfOwnerCell

                                atScrollPosition:UITableViewScrollPositionMiddle

                                        animated:YES];

    }

}


// 键盘将要消失时,执行该方法

- (void) handleKeyboardWillHide:(NSNotification *)paramNotification{

    // 比较两个EdgeInsets是否相等

    if (UIEdgeInsetsEqualToEdgeInsets(self.myTableView.contentInset, UIEdgeInsetsZero)){

        // 无需设置TableViewcontentInset

        return;

    }

    NSDictionary *userInfo = [paramNotification userInfo];

    NSValue *animationCurveObject =[userInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey];

    NSValue *animationDurationObject =[userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey];

    NSValue *keyboardEndRectObject =[userInfo valueForKey:UIKeyboardFrameEndUserInfoKey];

    NSUInteger animationCurve = 0;

    double animationDuration = 0.0f;

    CGRect keyboardEndRect = CGRectMake(0, 0, 0, 0);

    [animationCurveObject getValue:&animationCurve];

    [animationDurationObject getValue:&animationDuration];

    [keyboardEndRectObject getValue:&keyboardEndRect];

    

    [UIView beginAnimations:@"changeTableViewContentInset" context:NULL];

    [UIView setAnimationDuration:animationDuration];

    [UIView setAnimationCurve:(UIViewAnimationCurve)animationCurve];

    self.myTableView.contentInset = UIEdgeInsetsZero;

    [UIView commitAnimations];

}


3.取消键盘事件

// 关于观察者,什么时候添加?什么时候移除?

// 添加应该在页面载入后,一般是:viewDidLoadviewWillAppear方法中。

// 移除应该在viewWillDisappear方法中。因为,应该养成这么一个好习惯:当某个ViewController不在屏幕上显示时,应该及时将观察者移除。


- (void) viewWillDisappear:(BOOL)paramAnimated{

    [super viewDidDisappear:paramAnimated];

    // 移除观察者,当移除观察者时,观察者所注册的观察事件也会被移除。

    // 从通知中心移除某个通知观察者的所有通知项。换句话说:将观察者注册的所有通知项从通知中心移除。

    // 当然,也可以使用 removeObserver:name:object:方法,来单个移除。

    [[NSNotificationCenter defaultCenter] removeObserver:self];

}


4.小技巧

隐藏键盘,还有个方法

// 当点击键盘Return按钮时,将触发该方法

- (BOOL)textFieldShouldReturn:(UITextField *)textField{

    

    [textField resignFirstResponder];// 放弃第一响应者。

    

    return YES;

}


最后,附上完整源代码:

MoreViewController.h

#import


@interface MoreViewController : UIViewController<</span>UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate>{


}


@property (nonatomic, retain) UITableView *myTableView;


@end


MoreViewController.m

#import "MoreViewController.h"


@implementation MoreViewController

@synthesize myTableView;


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

{

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self) {

        

        // Custom initialization

    }

    return self;

}


- (void)dealloc{

    [super dealloc];

}




- (void)viewDidLoad{

    [super viewDidLoad];

    

    self.view.backgroundColor = [UIColor whiteColor];

    

    self.myTableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];

    [self.myTableView setDataSource:self];

    [self.myTableView setDelegate:self];

    self.myTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

    [self.view addSubview:self.myTableView];

   


}


// 当点击键盘Return按钮时,将触发该方法

- (BOOL)textFieldShouldReturn:(UITextField *)textField{

    

    [textField resignFirstResponder];// 放弃第一响应者。

    

    return YES;

}


#pragma mark- UITableViewDataSource


- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView{

    return 1;

}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

    

    return 100;

}


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

    UITableViewCell *result = nil;

    static NSString *CellIdentifier = @"CellIdentifier";

    result = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (result == nil){

        result = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

        result.selectionStyle = UITableViewCellSelectionStyleNone;

    }

    result.textLabel.text = [NSString stringWithFormat: @"Cell %ld", (long)indexPath.row];

    CGRect accessoryRect = CGRectMake(0.0f, 0.0f,150.0f,31.0f);

    UITextField *accesssory = [[UITextField alloc] initWithFrame:accessoryRect];

    accesssory.borderStyle = UITextBorderStyleRoundedRect;

    accesssory.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;

    accesssory.placeholder = @"Enter Text";

    accesssory.delegate = self;

    result.accessoryView = accesssory;

    return result;

}




- (void)viewDidUnload{

    [self setMyTableView:nil];

    [super viewDidUnload];


}


- (void) viewWillAppear:(BOOL)paramAnimated{

    [super viewDidAppear:paramAnimated];

    

    // 在通知中心注册观察者,并指定观察者感兴趣的事件

    

    // 键盘将要显示时

    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];

    [center addObserver:self

               selector:@selector(handleKeyboardWillShow:)

                   name:UIKeyboardWillShowNotification

                 object:nil];

    

    // 键盘将要隐藏时

    [center addObserver:self

               selector:@selector(handleKeyboardWillHide:)

                   name:UIKeyboardWillHideNotification

                 object:nil];

   

}



// 关于观察者,什么时候添加?什么时候移除?

// 添加应该在页面载入后,一般是:viewDidLoadviewWillAppear方法中。

// 移除应该在viewWillDisappear方法中。因为,应该养成这么一个好习惯:当某个ViewController不在屏幕上显示时,应该及时将观察者移除。


- (void) viewWillDisappear:(BOOL)paramAnimated{

    [super viewDidDisappear:paramAnimated];

    // 移除观察者,当移除观察者时,观察者所注册的观察事件也会被移除。

    // 从通知中心移除某个通知观察者的所有通知项。换句话说:将观察者注册的所有通知项从通知中心移除。

    // 当然,也可以使用 removeObserver:name:object:方法,来单个移除。

    [[NSNotificationCenter defaultCenter] removeObserver:self];

}


// 键盘出现时,调用该方法

- (void) handleKeyboardWillShow:(NSNotification *)paramNotification{

    NSDictionary *userInfo = [paramNotification userInfo];

    NSValue *animationCurveObject =[userInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey];

    NSValue *animationDurationObject =[userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey];

    NSValue *keyboardEndRectObject =[userInfo valueForKey:UIKeyboardFrameEndUserInfoKey];

    NSUInteger animationCurve = 0;

    double animationDuration = 0.0f;

    CGRect keyboardEndRect = CGRectMake(0, 0, 0, 0);

    [animationCurveObject getValue:&animationCurve];

    [animationDurationObject getValue:&animationDuration];

    [keyboardEndRectObject getValue:&keyboardEndRect];

    

    [UIView beginAnimations:@"changeTableViewContentInset" context:NULL];

    

    [UIView setAnimationDuration:animationDuration];

    [UIView setAnimationCurve:(UIViewAnimationCurve)animationCurve];

    

    UIWindow *window = [[[UIApplication sharedApplication] delegate] window];// 获得window

    // 得到window.frame和键盘frame的交集

    CGRect intersectionOfKeyboardRectAndWindowRect = CGRectIntersection(window.frame, keyboardEndRect);

    CGFloat bottomInset = intersectionOfKeyboardRectAndWindowRect.size.height;

    self.myTableView.contentInset = UIEdgeInsetsMake(0.0f,0.0f,bottomInset,0.0f);

    NSIndexPath *indexPathOfOwnerCell = nil;

    // 保证得到焦点的UITextField(文本框)也显示在屏幕上

    NSInteger numberOfCells = [self.myTableView.dataSource tableView:self.myTableView

                                               numberOfRowsInSection:0];

    

    // 循环,并且得到获得焦点的UITextField(文本框)所在的UITableViewCell中的NSIndexPath信息,并滚动TableView到相应的位置

    for (NSInteger counter = 0;counter < numberOfCells;counter++){

        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:counter inSection:0];

        UITableViewCell *cell = [self.myTableView cellForRowAtIndexPath:indexPath];

        UITextField *textField = (UITextField *)cell.accessoryView;

        if ([textField isKindOfClass:[UITextField class]] == NO){

            continue;

        }

        if ([textField isFirstResponder]){

            indexPathOfOwnerCell = indexPath;

            break;

        }

    }

    

    [UIView commitAnimations];

    

    // 滚动TableView到相应的位置

    if (indexPathOfOwnerCell != nil){

        [self.myTableView scrollToRowAtIndexPath:indexPathOfOwnerCell

                                atScrollPosition:UITableViewScrollPositionMiddle

                                        animated:YES];

    }

}


// 键盘将要消失时,执行该方法

- (void) handleKeyboardWillHide:(NSNotification *)paramNotification{

    // 比较两个EdgeInsets是否相等

    if (UIEdgeInsetsEqualToEdgeInsets(self.myTableView.contentInset, UIEdgeInsetsZero)){

        // 无需设置TableViewcontentInset

        return;

    }

    NSDictionary *userInfo = [paramNotification userInfo];

    NSValue *animationCurveObject =[userInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey];

    NSValue *animationDurationObject =[userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey];

    NSValue *keyboardEndRectObject =[userInfo valueForKey:UIKeyboardFrameEndUserInfoKey];

    NSUInteger animationCurve = 0;

    double animationDuration = 0.0f;

    CGRect keyboardEndRect = CGRectMake(0, 0, 0, 0);

    [animationCurveObject getValue:&animationCurve];

    [animationDurationObject getValue:&animationDuration];

    [keyboardEndRectObject getValue:&keyboardEndRect];

    

    [UIView beginAnimations:@"changeTableViewContentInset" context:NULL];

    [UIView setAnimationDuration:animationDuration];

    [UIView setAnimationCurve:(UIViewAnimationCurve)animationCurve];

    self.myTableView.contentInset = UIEdgeInsetsZero;

    [UIView commitAnimations];

}



#pragma mark - 旋转支持

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation

{

//    return UIInterfaceOrientationIsLandscape(toInterfaceOrientation);

    return YES;

}


-(BOOL)shouldAutorotate

{

    return YES;

}


-(NSInteger)supportedInterfaceOrientations

{

//    return UIInterfaceOrientationMaskLandscape;

    return UIInterfaceOrientationMaskAll;

}




@end



希望对你有所帮助!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值