ScrollView与Keyboard协同

原创 2013年12月03日 21:04:16

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结构,文档对其说明如下:




与其相对的还有一个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中软键盘弹出依然遮住控件

在一个Activity页面中,常会有需要用户输入的文本控件EditText,EditText获取焦点后,弹出的软键盘往往会遮挡底部的其他控件,通常处理方法是:1、xml布局中,使用ScrollView...
  • Peak1Chen
  • Peak1Chen
  • 2016年04月20日 16:38
  • 5612

keyboard弹出情况下scrollview被遮盖的处理方法

之前看到同事遇到使用tabelview显示Search Display Controller无法完全显示自动补全的搜索条目的问题,前两天学习的时候遇到storyboard实现的scrollview内部...
  • skyxfire
  • skyxfire
  • 2014年01月07日 14:40
  • 1085

IOS学习之scrollView与键盘协同

新建一个SingleViewApplication应用, 在storyboard中拖一个scrollView充满视图,拖三个Button,一个textField,如图: 其中第三个Butto...
  • avel__
  • avel__
  • 2015年02月03日 11:08
  • 272

React Native 应用在键盘弹出时优雅地响应

在使用 React Native 应用时,一个常见的问题是当你点击文本输入框时,键盘会弹出并且遮盖住输入框。就像这样: 有几种方式可以避免这种情况发生。一些方法比较简单,另一些稍微复杂。...
  • sinat_17775997
  • sinat_17775997
  • 2017年06月09日 10:01
  • 4010

Android自定义软键盘KeyboardView 使用实例

在有些应用中会有定制软键盘的需求,往往实现起来会有些难度,或者说实现出来的效果不尽如人意。...
  • yaosongqwe
  • yaosongqwe
  • 2015年12月06日 23:55
  • 6806

Unity中的协同函数

在学习unity3d的时候很容易看到下面这个例子: 1 void Start () { 2 StartCoroutine(Destroy()); 3 } 4 5 IEnumerator Des...
  • limu693992297
  • limu693992297
  • 2016年09月01日 16:05
  • 1667

从item-base到svd再到rbm,多种Collaborative Filtering(协同过滤算法)从原理到实现

〇.说明          本文的所有代码均可在 DML 找到,欢迎点星星。 一.引入           推荐系统(主要是CF)是我在参加百度的电影推荐算法比赛的时候才临时学的,虽然没拿什么奖,但是...
  • Dark_Scope
  • Dark_Scope
  • 2013年12月14日 19:49
  • 48935

协同过滤Item-based算法实现电影推荐系统

采用离线式计算推荐给每位用户的电影,采用Item-based算法并做了适当修改,主要分两部分: 1.计算电影的相似度:利用调整的余弦相似度计算方法; 2.相似度加权求和:使用用户已打分的电影的分数进行...
  • u013029603
  • u013029603
  • 2015年04月16日 22:43
  • 2075

搜集的十大协同过滤算法,仅供参考

推荐系统的一些开源实现
  • cc18868876837
  • cc18868876837
  • 2017年03月07日 10:44
  • 742

Android ScrollView嵌套ScrollView,并且嵌套的ScrollView超过屏幕部分

问题:我在ScrollView里面嵌套了一个ScrollView,嵌套的ScrollView超出了屏幕显示部分,需要向下滑动才能看到,当滑动下去找到嵌套的ScrollView时,滑动时并不能触发它的o...
  • wangsidadehao
  • wangsidadehao
  • 2016年08月14日 14:53
  • 4795
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ScrollView与Keyboard协同
举报原因:
原因补充:

(最多只允许输入30个字)