这两天练着画表单界面,用UITableView做了一个表单。表单加载了三种单元格,其中有一种Cell放的是Textfield,现在想实现一个功能(这个功能在招商银行app的理财计算器里已经实现了):
点击文本框后在弹出的小键盘上增加两个方向按钮,点击按钮上下移动光标,并且滑动表格让被遮盖的文本框可见。
但是试了好几个长得像的方法(scrollRectToVisible、selectRowAtIndexPath、setContentOffset、scrollToRowAtIndexPath),都没滑动效果,而且当文本框超出屏幕后连聚焦都不起作用了,可是屏幕外的Cell并没有被释放啊,这是为什么。
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger section = indexPath.section;
NSInteger row = indexPath.row; //获取行号
UserItem *userItem = [[self.dataList objectAtIndex:section ] objectAtIndex:row];//获取数据
NSString *Indentifier=[NSString stringWithFormat:@"NEW_Default_Cell_%@",userItem.title];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Indentifier];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:Indentifier];
if([userItem.inputType isEqualToString:@"box"])
{
ComboboxCell *comboboxCell = nil;
NSArray *objects = [[NSBundle mainBundle] loadNibNamed:@"ComboboxCell" owner:self options:nil];
for (NSObject *o in objects) {
if ([o isKindOfClass:[ComboboxCell class]]) {
comboboxCell = (ComboboxCell *)o;
break;
}
}
comboboxCell.lblTitle.text = userItem.title;
if(userItem.value == nil ||[userItem.value isEqualToString:@""])
{
comboboxCell.lblValue.textColor = [UIColor grayColor];
comboboxCell.lblValue.text = userItem.placeholder;
}else
{
comboboxCell.lblValue.textColor = [UIColor blackColor];
comboboxCell.lblValue.text = userItem.value;
}
[cell.contentView addSubview:comboboxCell.contentView];
//NSLog(@"创建单元格:%@",userItem.title);
}else if([userItem.inputType isEqualToString:@"arrow"])
{
ComboArrowCell *comboArrayCell = nil;
NSArray *objects = [[NSBundle mainBundle] loadNibNamed:@"ComboArrowCell" owner:self options:nil];
for (NSObject *o in objects) {
if ([o isKindOfClass:[ComboArrowCell class]]) {
comboArrayCell = (ComboArrowCell *)o;
break;
}
}
NSString *imageName = [[NSBundle mainBundle] pathForResource:@"icon_arrows@2x" ofType:@"png"];
UIImage *image = [UIImage imageWithContentsOfFile:imageName];
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
// IOS7.0以后版本需要对图像进行处理
// 设置未选中图片
[image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}
comboArrayCell.lblTitle.text = userItem.title;
if(userItem.value ==nil ||[userItem.value isEqualToString:@""])
{
comboArrayCell.lblValue.textColor = [UIColor grayColor];
comboArrayCell.lblValue.text = userItem.placeholder;
}else
{
comboArrayCell.lblValue.textColor = [UIColor blackColor];
comboArrayCell.lblValue.text = userItem.value;
}
comboArrayCell.imgView.image = image;
[cell.contentView addSubview:comboArrayCell.contentView];
//NSLog(@"创建单元格:%@",userItem.title);
}else
{
TextFieldCell *textFieldCell=nil;
NSArray *objects = [[NSBundle mainBundle] loadNibNamed:@"TextFieldCell" owner:self options:nil];
for (NSObject *o in objects) {
if ([o isKindOfClass:[TextFieldCell class]]) {
textFieldCell = (TextFieldCell *)o;
break;
}
}
textFieldCell.lblTitle.text = userItem.title;
textFieldCell.textField.text = userItem.value;
textFieldCell.textField.placeholder = userItem.placeholder;
if(self.textFieldList == nil)
{
self.textFieldList = [[NSMutableArray alloc]init];
self.points = [[NSMutableArray alloc]init];
}
[self.textFieldList addObject:textFieldCell.textField];//记录文本框
CellPostion *cellPostion = [[CellPostion alloc]initWithParameters:section andRow:row];
[self.points addObject:cellPostion];
UIBarButtonItem *leftArrow=[[UIBarButtonItem alloc]initWithTitle:@" < " style:UIBarButtonItemStyleDone target:self action:@selector(leftArraw)];
UIBarButtonItem *rightArrow=[[UIBarButtonItem alloc]initWithTitle:@" > " style:UIBarButtonItemStyleDone target:self action:@selector(rightArraw)];
[textFieldCell initAction:leftArrow andRightArrow:rightArrow];
[cell.contentView addSubview:textFieldCell];
//NSLog(@"创建单元格:%@",userItem.title);
}
}
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
return cell;
}
#pragma mark - Action
//点击向左的箭头
-(void)leftArraw//:(NSInteger) section andRow:(NSInteger) row
{
for (int i=0; i<self.textFieldList.count; i++) {
if ([self.textFieldList[i] isFirstResponder]) {
[self.textFieldList[i] resignFirstResponder];//光标所在的文本框交出第一响应
if(i>0)
{
CellPostion *oldPostion = self.points[i];//光标所在的文本框,CellPostion存了cell的section和row两个字段
CellPostion *newPostion = self.points[i-1];//下一个文本框
int lineCount1 = oldPostion.row;//计算当前文本框距离顶部的Cell数量
for(int i=0;i<oldPostion.section;i++)
{
lineCount1 += [[self.dataList objectAtIndex:i] count];
}
int lineCount2 = newPostion.row;//计算下一个文本框距离顶部的Cell数量
for(int i=0;i<newPostion.section;i++)
{
lineCount2 += [[self.dataList objectAtIndex:i] count];
}
int height = (lineCount1 - lineCount2) * 45;//两个文本框的距离
//[self.tableActivies scrollRectToVisible:CGRectMake(0, height, 240, 45) animated:YES];
// [self.tableActivies selectRowAtIndexPath:[NSIndexPath indexPathForRow:newPostion.row inSection:newPostion.section]
// animated:YES
// scrollPosition:UITableViewScrollPositionMiddle];
[self.tableActivies setContentOffset:CGPointMake(0, height) animated:YES];
// [self.tableActivies scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:newPostion.row inSection:newPostion.section] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
[self.textFieldList[i - 1] becomeFirstResponder];
}
break;
}
}
}
既然你计算出了偏移距离,你直接 将 整个tableView 通过动画上移或者 下移 就可以了吧,而不是去处理 里面的内容。
[UIView animateWithDuration:0.2 animations:^{
self.tableActivies .transform = CGAffineTransformMakeTranslation(0, -height);
}completion:^(BOOL finished) {
}];
果然发现了一个小问题,上面的代码中leftArraw 中需要指定类型为TextFieldCell ,这样才能访问它的textField 属性
-(void)leftArraw {
/////先找到当前焦点所在的cell
TextFieldCell *curCell = nil;
NSInteger curIndex = 0;
for (int i=0; i<self.textFieldCells.cout; i++) {
TextFieldCell *cell = (TextFieldCell *)self.txtFieldCells[i];
if ([cell.textField isFirstResponder]) { /////判断是否为焦点cell
curCell = cell; ////找到当前焦点cell
curIndex = i; /////保存索引
break; //////退出for
}
}
if (curCell) { //////判断当前焦点cell是否找到
if (curIndex ==0 )
return; /////如果已经到了最顶的那个cell,则什么也不处理
curIndex = curIndex -1 ; //////向上找
TextFieldCell *preCell = (TextFieldCell *)self.textFieldCells[curIndex];
[curCell.textField resignFirstResponder]; /////失去焦点
[preCell.textField becomeFirstResponder]; /////获取焦点
[self.tableView scrollToRowAtIndexPath:preCell.indexPath]; /////滚动到这个位置
}
}