最近做的项目有个需求,大致如下图所示,用户在一个tableview界面里面的textview输入内容,textview根据用户输入的内容多少自动改变大小以及换行,而且tableviewcell的高度也要随着textview高度的变化而跟着变化。
我的实现思路是先解决textview随输入内容变化以及换行问题,这个先在cellfoRowAtIndexpath里直接使用sizeToFit方法,然后计算sizeToFit后的textview的高度,并用成员变量CGFloat _height 记录,将这个高度+20后通过heightforRowAtIndexPath方法返回。这样可以保证tableViewCell的高度根据textView的高度而变化。这是由于目前的iOS构建tabelView的顺序是先执行cellForRowAtIndexPath,再执行heightForRowAtIndexPath。
下一步要实现,当textview有内容输入时,尤其是换行的时候tableViewCell的高度也要实施动态变化,这个地方的问题在于要改变tableViewCell的高度,肯定需要reloadData,可如果在textviewDidChange里面对tableview进行reloadData,会结束当前的输入,为了让用户继续在该textview进行输入,就需要在每次reloadData以后自动将该textView设置为第一响应者,使其处于编辑状态。而要想使该textview成为第一响应者,首先要在viewDidAppear方法里使用cellForRowAtIndexpath方法获得其所在的cell,至于为什么要在viewDidAppear方法里而不是viewWillAppear或者viewDidLoad方法,是因为在那两个方法里获取到的cell始终为空。
大概思路就是这样,下面是代码。这个方法可能不是最好的,欢迎大家讨论。
#import "ViewController.h"@interface ViewController (){
int _flag;
CGFloat _height;
}
@property (nonatomic ) CGRect textViewFrame;
@property (nonatomic,strong) UITableView* tableView;
@property (nonatomic,strong) NSMutableArray* strArray;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_strArray= [[NSMutableArray alloc]initWithArray:@[@"aaa",@"aaa",@"aaa",@"aaa",@"aaa",@"aaa",@"aaa",@"aaa",@"aaa",@"aaa"]];
self.view.backgroundColor=[UIColor grayColor];
UITableView* tableView=[[UITableView alloc]initWithFrame:CGRectMake(30, 30, self.view.bounds.size.width-60, self.view.bounds.size.height-60) style:UITableViewStylePlain];
tableView.backgroundColor=[UIColor orangeColor];
tableView.delegate=self;
tableView.dataSource=self;
_tableView=tableView;
[self.view addSubview:_tableView];
}
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSIndexPath* indexpath=[NSIndexPath indexPathForRow:_flag inSection:0];
UITableViewCell* cell=[self.tableView cellForRowAtIndexPath:indexpath];
if(cell)
{
UITextView* textview=cell.contentView.subviews[0];
[textview becomeFirstResponder];
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell=[[UITableViewCell alloc]init];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
cell.backgroundColor=[UIColor purpleColor];
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
UITextView* textView=[[UITextView alloc]initWithFrame:CGRectMake(15, 5,100, cell.frame.size.height-10) textContainer:nil];
textView.tag=indexPath.row;
textView.text=_strArray[indexPath.row];
[textView sizeToFit];//使用sizeToFit方法处理textview随输入大小变化以及自动换行问题
_height=textView.frame.size.height; //_height记录textview高度
textView.delegate=self;
textView.scrollEnabled=NO;
[cell.contentView addSubview:textView];
return cell;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 10;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(_height==0)
{
return 50;
}
else{
return _height+10;
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell=[tableView cellForRowAtIndexPath:indexPath];
for(UIView* view in cell.contentView.subviews)
{
if([view isKindOfClass:[UITextView class]])
{
[view becomeFirstResponder];
}
}
}
-(BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
self.textViewFrame = [textView convertRect:textView.frame toView:self.view];
return YES;
}
- (void)textViewDidChange:(UITextView *)textView
{
_strArray[textView.tag]=textView.text;
_flag=(int)textView.tag;
[self.tableView reloadData];
[self viewDidAppear:YES];
}
@end