ScrollView与Keyboard协同

ScrollView对应于UIKit中UIScrollView类,是容器视图。它有两个子类——UITextView和UITableView,它们在内容超出屏幕时提供水平或垂直方向的滚动条。

ScrollView的属性有很多,比较重要的与显示有关的有:contentSize、contentInset和contentOffset。


1、contentSize

contentSize属性表示ScrollView中内容视图的大小,它返回CGSize结构体类型。ScrollView的范围由frame属性指定。当contentSize范围超出frame指定的范围时,ScrollView才提供滚动。


2、contentInset

contentInset属性用于在ScrollView中的内容视图周围添加边框(contentInset有四个分量,分别是Top、Bottom、Left和Right),这往往为了留出空白以放置工具栏、标签栏或者导航栏等。


3、contentOffset属性是内容视图坐标原点与ScrollView坐标原点的偏移量,返回CGPoint结构体类型。


在IOS开发中,键盘是很麻烦的。显示键盘时会遮挡一些控件。如何使界面中的众多控件与键盘很好地协同,给用户较好的体验呢?这里的关键在于键盘打开前后,调整控件的位置。


在我们的这里,ScrollView在竖直方向上依次放置两个Button和一个TextField(控件之间有一定的距离)。当键盘隐藏时,三个控件刚好能摆放得下。我们的需求是,当TextField获得焦点键盘弹出时,调整ScrollView的高度,并使得TextField当前可见。TextField输入完成后,点击return隐藏键盘,这时候ScrollView恢复原来大小。


为了在键盘显示和隐藏时做相应的处理,我们要注册接收键盘显示和隐藏消息。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
    
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];


-(void)keyboardDidShow:(NSNotification*) notification
{
    if(keyboardVisible){
        return;
    }
    
    //获取键盘尺寸
    CGSize keyboardSize=[self getSizeWithKeyboardNotification:notification];
    //重新定义scrollview的尺寸
    CGRect scrollViewFrame=self.mScrollView.frame;
    scrollViewFrame.size.height-=keyboardSize.height;
    self.mScrollView.frame=scrollViewFrame;
    
    //滚动到TextField
    CGRect textFieldFrame=self.mTextField.frame;
    [self.mScrollView scrollRectToVisible:textFieldFrame animated:YES];
    
    keyboardVisible=YES;
}

-(void)keyboardDidHide:(NSNotification*) notification
{
    //获取键盘尺寸
    CGSize keyboardSize=[self getSizeWithKeyboardNotification:notification];
    
    //重新定义scrollview的尺寸
    CGRect scrollViewFrame=self.mScrollView.frame;
    scrollViewFrame.size.height+=keyboardSize.height;
    self.mScrollView.frame=scrollViewFrame;
    
    if(!keyboardVisible){
        return;
    }
    keyboardVisible=NO;
}

-(CGSize)getSizeWithKeyboardNotification:(NSNotification*)notification
{
    NSDictionary* userInfo=[notification userInfo];
    NSValue* value=[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
    CGSize keyboardSize=[value CGRectValue].size;
    return keyboardSize;
}

这个由系统发出的UIKeyboardDidShowNotification通知中传递NSDictionary类型的数据,可以使用userInfo类获取该数据。使用UIKeyboardFrameEndUserInfoKey取出其中键盘的Frame值。UIKeyboardFrameEndUserInfoKey对应的是个NSValue对象,内部包含CGRect结构,文档对其说明如下:


ScrollView与Keyboard协同_第1张图片


与其相对的还有一个UIKeyboardFrameBeginUserInfoKey,说明如下:




上面是在键盘显示和隐藏时对ScrollView的size的调整。这里我们还有一个问题,键盘的隐藏问题。在IOS中,一旦TextField和TextView等控件处于编辑状态,系统就会只能地弹出键盘,而不需要做任何额外的操作。但是,关闭键盘就不像打开键盘这样顺利了,我们需要用代码去实现。


首先我们要了解键盘不能自动关闭的原因。当TextField或TextView处于编辑状态时,这些控件成了“第一响应者”。要关闭键盘,就要放弃“第一响应者”的身份。在IOS中,事件沿着响应者链从一个响应者传到下一个响应者,如果其中一个响应者没有对事件做出响应,那么该事件会继续向下传递。


顾名思义,“第一响应者”是响应者链中的第一个,不同的控件成为“第一响应者”之后的表现不太一样。输入类控件会出现键盘,而我们只有让这些控件放弃它们的“第一响应者”身份,键盘才会关闭。


要想放弃“第一响应者”身份,需要调用UIResponder类中的resignFirstResponder方法,此方法一般在点击return键或者背景图时触发。由于TextField只能单行输入,所以这里我们在return键触发时关闭键盘。


-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    return YES;
}

textFieldShouldReturn:方法是UITextFieldDelegate委托协议中定义的方法,在用户点击键盘return时调用。


ScrollView与Keyboard协同_第2张图片



你可能感兴趣的:(ios,uiscrollview,keyboard,IOS键盘隐藏)