ios - UITableViewController 返回到单元格中的下一个文本字段
问题描述
我有一个 UITableViewController 和一个实现 UITableView 的类。
@interface CreateEditViewController : UITableViewController<UITextFieldDelegate>
@end
我还有一个实现 UITableViewCell 的类,每个 Cell 都包含一个文本字段。
@interface CreateEditCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UITextField *celltextfield;
@end
在我的 TableView 控制器类中,我实现了这三种方法cellForRowAtIndexPath
,numberOfRowsInSection
并且textFieldShouldReturn
在我的cellForRowAtIndexPath
我将每个单元格的文本字段委托分配给 self 并在 switch case 中给每个单元格一个标签。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
CreateEditCell* cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
cell.celltextfield.delegate = self;
cell.celltextfield.returnKeyType = UIReturnKeyNext;
switch (indexPath.row) {
case 0:
cell.celltextfield.tag = 0;
break;
case 1:
cell.celltextfield.tag = 1;
break;
case 2:
cell.celltextfield.tag = 2;
break;
case 3:
cell.celltextfield.tag = 3;
break;
}
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 4;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
NSInteger nexttag = textField.tag+1;
UIResponder* nextresponder = [textField.superview viewWithTag:nexttag];
if(nextresponder){
[nextresponder becomeFirstResponder];
}else{
[textField resignFirstResponder];
NSLog(@"Nothing to return to");
}
return NO;
}
因此,返回下一个文本字段在我之前的设计中起作用,我没有由单元格动态生成文本字段。相反,我在故事板上有单独的文本字段,并在 viewdidload 中分配了它们的标签。但是现在使用当前的设计,当我点击返回按钮而不是转到下一个单元格时,它只会打印“Nothing to return”,这没有意义,因为我有四个单元格(四个文本字段),每个单元格都有自己的独特的标签。所以我的问题是,如何使用我拥有的当前设计返回下一个文本字段。
解决方案
问题是您的设计更改也导致您的文本字段的视图层次结构更改。它们不再是直接的兄弟姐妹,而是托管在表格视图中的单元格中。因此,当您关注一个新的文本字段时,您必须找到承载该文本字段的单元格,而且,此单元格可能不可见,因此您需要先滚动到它。
因此:
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
NSInteger nexttag = textField.tag+1;
if (nexttag < [self.tableView numberOfRowsInSection:0]) {
NSIndexPath *nextIndexPath = [NSIndexPath indexPathForRow:nexttag inSection:0];
[self.tableView scrollToRowAtIndexPath:nextIndexPath atScrollPosition:UITableViewScrollPositionNone animated:YES];
CreateEditCell* cell = [self.tableView cellForRowAtIndexPath:nextIndexPath];
if (cell == nil) {
// cell is not displayed at the moment, therefore we
// "force-scroll" (without animation) to it
// and then retrieve it again:
[self.tableView scrollToRowAtIndexPath:nextIndexPath atScrollPosition:UITableViewScrollPositionNone animated:NO];
cell = [self.tableView cellForRowAtIndexPath:nextIndexPath];
}
[cell.celltextfield becomeFirstResponder];
}else{
[textField resignFirstResponder];
NSLog(@"Nothing to return to");
}
return NO;
}
这段代码有点快速和肮脏,因为如果单元格不可见,则无法通过调用来检索它cellForRowAtIndexPath
。即使是动画scrollToRowAtIndexPath
也无济于事,因为您需要等待显示单元格。所以我的解决方法只是再次滚动,没有动画。
一个更好的解决方案是实现UIScrollViewDelegate
,scrollViewDidEndScrollingAnimation
然后您可以集中文本字段 - 但请注意,只有在滚动是由用户滚动活动引起textFieldShouldReturn
而不是由用户滚动活动引起时,您才应该这样做。因此,您将使用一个标志(或更好:自定义委托/闭包),您可以检查它以确定哪种滚动动画结束了。
推荐阅读
- javascript - 如何从对象中删除字段
- javascript - Frida - Calling a specific method overload
- logging - 如何以编程方式启用登录 apache cxf jax-rs 客户端
- android - 如何在 Android 的 AlertDialog 中将最大高度设置为列表视图?
- firebase - 构建函数返回 null。颤振火力基地
- java - 在 Spring Boot 中使用两个数据源
- azure - PowerShell脚本让所有章鱼环境部署变量在环境范围内表现出色
- google-sheets - Google 表格中的 BigQuery 连接器限制为 10,000 行
- python-3.x - 自定义 k-means 聚类 GridSearchCV
- java - 如何使用@SpringBootTest 验证作业是否运行了另一个作业