求助,想点击按钮让UITableView滑动,试了几个方法没效果

皮蛋 2015-05-22 01:47:04

在学ios , 这两天练着画表单界面,用UITableView做了一个表单。表单加载了三种单元格,其中有一种Cell放的是Textfield,现在想实现一个功能(这个功能在招商银行app的理财计算器里已经实现了):
点击文本框后在弹出的小键盘上增加两个方向按钮,点击按钮上下移动光标,并且滑动表格让被遮盖的文本框可见。
但是试了好几个长得像的方法(scrollRectToVisible、selectRowAtIndexPath、setContentOffset、scrollToRowAtIndexPath),都没滑动效果而且当文本框超出屏幕后连聚焦都不起作用了,可是屏幕外的Cell并没有被释放啊,这是为什么
创建Cell和添加箭头按钮&点击事件的代码如下,级别低只能放100分了:





- (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;
}
}
}

...全文
356 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
皮蛋 2015-06-12
  • 打赏
  • 举报
回复
引用 5 楼 zhanglei5415 的回复:
[quote=引用 4 楼 vxbb_free 的回复:] [quote=引用 3 楼 zhanglei5415 的回复:] 果然发现了一个小问题,上面的代码中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]; /////滚动到这个位置
         }
}
遍历visibleCells 发现里面元素是 0 个。[/quote] 访问的时机对吗?不可能为0个,只要有已经显示出来的cell ,这个visibleCells 中就有值 [/quote] 发现问题原因了,是我把xib上table又alloc了一次;
皮蛋 2015-05-22
  • 打赏
  • 举报
回复
引用 5 楼 zhanglei5415 的回复:
[quote=引用 4 楼 vxbb_free 的回复:] [quote=引用 3 楼 zhanglei5415 的回复:] 果然发现了一个小问题,上面的代码中leftArraw 中需要指定类型为TextFieldCell ,这样才能访问它的textField 属性
-(void)leftArraw {
            ^……
         }
}
遍历visibleCells 发现里面元素是 0 个。[/quote] 访问的时机对吗?不可能为0个,只要有已经显示出来的cell ,这个visibleCells 中就有值 [/quote] 点击按钮触发 leftArraw事件 ---> 访问 self.textFieldCells ---> 然后调用self.tableView.visibleCells; NSArray *visibleCells = self.tableView.visibleCells;打断点发现visibleCells个数是0; 我把代码上传了, http://download.csdn.net/detail/vxbb_free/8727353 现在公司上班,没法再调试了,版主要是有空帮忙看看吧 谢谢
ReyZhang 2015-05-22
  • 打赏
  • 举报
回复
引用 4 楼 vxbb_free 的回复:
[quote=引用 3 楼 zhanglei5415 的回复:] 果然发现了一个小问题,上面的代码中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]; /////滚动到这个位置
         }
}
遍历visibleCells 发现里面元素是 0 个。[/quote] 访问的时机对吗?不可能为0个,只要有已经显示出来的cell ,这个visibleCells 中就有值
皮蛋 2015-05-22
  • 打赏
  • 举报
回复
引用 3 楼 zhanglei5415 的回复:
果然发现了一个小问题,上面的代码中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]; /////滚动到这个位置
         }
}
遍历visibleCells 发现里面元素是 0 个。
ReyZhang 2015-05-22
  • 打赏
  • 举报
回复
果然发现了一个小问题,上面的代码中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]; /////滚动到这个位置
         }
}
ReyZhang 2015-05-22
  • 打赏
  • 举报
回复
我觉得你可以这样,在第一次显示时所有的类型为 TextFieldCell 的cell 都在可视范围内,可以通过visiableCells来得到所有可视 cell的集合。 遍历这个集合,得到所有的class为TextFieldCell 的cell,放到一个数组中,这样在查找时就不需要再全部遍历只需要从这个数组中查找就可以了.定义一个textFieldCells 属性,自定义getter方法
-(NSMutableArray *)textFieldCells {
        if (_textFieldCells == nil) {
              _textFieldCells = [[NSMutableArray alloc] init];
              for (UITableViewCell *cell in self.tableView.visibleCells) {  /////遍历所有可视的cell集合
                      if ([cell isKindOfClass:[TextFieldCell class]]) {   /////判断cell的类型是否为TextFieldCell 
                              [_textFieldCells addObject:cell];   //////将类型为TextFieldCell 的cell加入到集合
                      }
              }
        }
        return _textFieldCells;
}

-(void)leftArraw {
          /////先找到当前焦点所在的cell
         UITableViewCell *curCell = nil;
         NSInteger curIndex = 0;
         for (int i=0; i<self.textFieldCells.cout; i++) {
                UITableViewCell *cell = 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 ; //////向上找
                UITableViewCell *preCell = self.textFieldCells[curIndex];
                [curCell.textField resignFirstResponder];   /////失去焦点
                [preCell.textField becomeFirstResponder]; /////获取焦点
                [self.tableView scrollToRowAtIndexPath:preCell.indexPath]; /////滚动到这个位置
         }
}
以上代码纯手写,可能有不对之处。自己判断
ttpsan550 2015-05-22
  • 打赏
  • 举报
回复
既然你计算出了偏移距离,你直接 将 整个tableView 通过动画上移或者 下移 就可以了吧,而不是去处理 里面的内容。

[UIView animateWithDuration:0.2 animations:^{
    self.tableActivies .transform = CGAffineTransformMakeTranslation(0, -height);
    
}completion:^(BOOL finished) {
    
}];

29,028

社区成员

发帖
与我相关
我的任务
社区描述
主要讨论与iOS相关的软件和技术
社区管理员
  • iOS
  • 大熊猫侯佩
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧