自动滚动的 tableView 和高度自适应的 textView
来源:互联网 发布:淘宝买真货退假货犯法 编辑:程序博客网 时间:2024/06/05 09:49
先来看看效果图:
每一行 cell 类似于空间里的一条说说。
从第一幅图中可以看到,当点击某一条说说的评论按钮时,键盘弹出来后 tableView 会自动滚动,直到这条说说正好出现在输入框上方为止。
如果不这么做,这一条说说就会被键盘挡住,这样肯定不行。
能考虑到这一点只是最基础的。你给别人评论的时候,textView 肯定不是一开始就很多行吧?如果写了好几行怎么办?
首先 textView 要高度自适应,能想到这一点只是最基本的。我们再想想,textView 变高了,那岂不是又会挡住这条说说了吗?所以此时还要让 tableView 自动滚动。(看第二幅图)
上面这些都是纸上谈兵。说了那么多,有的人会问:“tableView 到底怎么滚动?”
简单来说就一句话:
[self.myTableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionBottom];
- (void)selectRowAtIndexPath:(nullable NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition;
它有三个参数,indexPath 就是你想滚动的那个cell,animated 决定是否有动画效果,scrollPosition 是一个枚举:
typedef NS_ENUM(NSInteger, UITableViewScrollPosition) { UITableViewScrollPositionNone, UITableViewScrollPositionTop, UITableViewScrollPositionMiddle, UITableViewScrollPositionBottom};
注意,它不是滚动的方向,而是滚动结束后这个 cell 相对于 tableVIew 的位置。比如说设置为 UITableViewScrollPoistionTop,那么滚动结束后这个 cell 就会处于屏幕最上面。如果设置为 UITableViewScrollViewPositionNone,那么 tableView 就不会滚动。显然我们需要设置为 UITableViewScrollPositionBottom。
我们先说简单的,假设评论永远只有一行,此时我们只需要考虑键盘弹出来以后让 tableVIew 滚动就行了。
那要怎么做呢?监听键盘。
- (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didShowKey:) name:UIKeyboardDidChangeFrameNotification object:nil];}
当键盘的 frame 发生变化时,就会调用我们自定义的 didShowKey:方法。
- (void)didShowKey:(NSNotification *)notific { NSDictionary *userInfo = notific.userInfo; // Get the origin of the keyboard. CGRect rect = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; CGFloat h = 0.0f; if (fabs(rect.origin.y - ScreenHeight) < 1e-3) { self.tableView.frame = CGRectMake(0, 0, ScreenWidth, ScreenHeight); } else { h = fmax(self.commentInputView.frame.size.height, 60.0f); self.tableView.frame = CGRectMake(0, 0, ScreenWidth, rect.origin.y - h + 44); } [self.tableView selectRowAtIndexPath:self.selectedIndexPath animated:YES scrollPosition:UITableViewScrollPositionBottom]; // Get the duration of the animation. NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; [UIView animateWithDuration:duration animations:^{ self.commentInputView.frame = CGRectMake(0, rect.origin.y - h, ScreenWidth, h); }];}
从代码中我们可以看到,其实当键盘弹出来时,我们是把 tableView 的高度变小了,然后让对应的 cell 滚动到 tableView 的下面。当收回键盘时,再把 tableView 的高度变回为屏幕的高度即可。
那么如果评论有多行怎么办?
我们需要实现 UITextViewDelegate 中的两个方法:
1. - (void)textViewDidChange:(UITextView *)textView;
2. - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
在这两个方法中动态计算 textView 中的文字高度(具体计算方法见我的另一篇文章:传送门),然后通过代理或者block,把高度返回给 controller,在 controller 中再次修改 tableView 的高度即可。
举个栗子吧:
- (void)textViewDidChange:(UITextView *)textView { CGFloat height = [self contentSizeOfText:textView.text]; _offsetY = self.frame.origin.y; if (height != self.frame.size.height) { _offsetY = _offsetY - (height - self.frame.size.height); self.frame = CGRectMake(0, _offsetY, [UIScreen mainScreen].bounds.size.width, height); if (self.changeFrame) { self.changeFrame(_offsetY); } } textView.frame = CGRectMake(0, 0, self.frame.size.width, height);}
contentSizeOfText:是自定义的计算指定文字高度的方法。
if (height != self.frame.size.height) 就是说,如果 textView 的高度发生了改变,那么我就需要把新的高度传给 controller。
在这里我们就举个 block 的栗子吧,changeFrame 就是我们自定义的 block,它有一个参数,这个参数就是我们需要传给 controller 的 textView 的高度。然后在 controller 中实现这个 block 即可:
__weak typeof(self) weakSelf = self;_commentInputView.inputViewFrameChanged = ^(CGRect aFrame) { CGRect frame = weakSelf.tableView.frame; frame.size.height = aFrame.origin.y + 44; weakSelf.tableView.frame = frame; [weakSelf.tableView scrollToRowAtIndexPath:weakSelf.selectedIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];};
主要的部分就是这些,当然还有很多细节部分,完整的代码见我的 github:传送门。别忘了点击右上角的 star 哦~
- 自动滚动的 tableView 和高度自适应的 textView
- IOS TableView的Cell高度自适应,UILabel自动换行适应
- IOS TableView的Cell高度自适应,UILabel自动换行适应
- IOS TableView的Cell高度自适应,UILabel自动换行适应
- ios TableView的Cell高度自适应,UILabel自动换行适应
- IOS TableView的Cell高度自适应,UILabel自动换行适应
- IOS TableView的Cell高度自适应,UILabel自动换行适应
- IOS TableView的Cell高度自适应,UILabel自动换行适应
- IOS TableView的Cell高度自适应,UILabel自动换行适应
- TableView的Cell高度自适应,UILabel自动换行适应
- IOS TableView的Cell高度自适应,UILabel自动换行适应
- IOS TableView的Cell高度自适应,UILabel自动换行适应
- IOS TableView的Cell高度自适应,UILabel自动换行适应
- tableView 的cell自适应高度
- textview自适应高度的计算方法
- UILable的自动换行和自适应高度
- IOS TableView的Cell高度自适应,UILabel自动换行适应 table里控件位置自适应
- 自动滚动的TextView
- 解读node.js的cluster模块
- Android中启动第三方程序的代码
- unhandled exception: Cannot load libssl.so.0.9.8
- java 异常处理机制
- Android Studio - Session 'app': Error launching activity
- 自动滚动的 tableView 和高度自适应的 textView
- 栈的一些习题
- 烟草零售聚类1、KM_classic
- 设计模式
- android 菜单
- Jenkins进阶系列之——03parameterized-trigger插件
- Android面试题
- JAVA BigDecimal 小数点处理
- Android Studio制作library(图解)