在我的应用中,我有一个非常大的表格可以填写。表单本身是使用表格视图和静态单元格模式。每个单元格包含标签和文本字段。我想在键盘上方添加一个工具栏,以便在文本字段之间导航。我做到了,但它表现得非常奇怪(至少我认为)。
跳转到下一个文本字段时没有问题,只有在可见时跳转到上一个文本字段才有可能。如果它不可见,旧的文本字段保持第一响应者,但是当我滚动我的表视图并且预期的文本字段变得可见时,它成为第一个响应者(我没有点击它!)。那么这当然不是我想要的行为。
我的问题是:这种行为是否正常?你能以某种方式绕过它吗?
如果您想亲眼看到这种行为,我已经上传了一个Xcode项目来说明问题。您可以在此处下载压缩项目:download。代码的主要部分解释如下。
我使用静态单元格设置了分组表格视图。每个都包含一个标签和textfield
。我为每个文本字段创建了出口以获取对它们的访问权限。在我的viewDidLoad方法中,我创建工具栏及其按钮,将文本字段存储在一个数组中,并将控制器设置为textfields委托。
- (void)viewDidLoad
{
[super viewDidLoad];
// create the keyboard toolbar with navigation elements
self.keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];
UIBarButtonItem *prevButton = [[UIBarButtonItem alloc] initWithTitle:@"Previous" style:UIBarButtonItemStyleBordered target:self action:@selector(prevClicked:)];
UIBarButtonItem *nextButton = [[UIBarButtonItem alloc] initWithTitle:@"Next" style:UIBarButtonItemStyleBordered target:self action:@selector(nextClicked:)];
[self.keyboardToolbar setItems:[NSArray arrayWithObjects:prevButton, nextButton, nil]];
// create the field chain
self.fields = [NSArray arrayWithObjects:self.aField, self.bField, self.cField, self.dField, self.eField, self.fField, nil];
// for scrolling and keeping track of currently active field
NSInteger max = [self.fields count];
for(NSInteger i = 0; i < max; i++) {
UITextField *curr = (UITextField *)[self.fields objectAtIndex:i];
curr.delegate = self;
}
}
文本字段委托方法存储活动文本字段的引用,并防止插入换行符。
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
textField.inputAccessoryView = self.keyboardToolbar;
return YES;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
// set the current active textfield
self.currentField = textField;
// scroll this textfield to top
UITableViewCell *cell = (UITableViewCell *)textField.superview.superview;
[self.tableView scrollToRowAtIndexPath:[self.tableView indexPathForCell:cell] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
self.currentField = nil;
return NO;
}
最后,工具栏按钮的选择器和获取下一个文本字段的逻辑。
- (void)moveResponderByStep:(NSInteger)step
{
// only move if a textfield is the current responder
if(![self.currentField isEditing]) {
return;
}
// where we are and where to move
NSInteger max = [self.fields count];
NSInteger moveToNumber;
for(NSInteger i = 0; i < max; i++) {
if(self.currentField == [self.fields objectAtIndex:i]) {
moveToNumber = i + step;
}
}
// stay in bounds
if(moveToNumber >= max || moveToNumber < 0) {
[self.currentField resignFirstResponder];
return;
}
// move on
UITextField *next = [self.fields objectAtIndex:moveToNumber];
[next becomeFirstResponder];
}
- (void)prevClicked:(id)sender
{
[self moveResponderByStep:-1];
}
- (void)nextClicked:(id)sender
{
[self moveResponderByStep:1];
}
谢谢!
答案 0 :(得分:0)
首先尝试检查该行是否可见。如果不是,则将行滚动到可见。然后将文本字段设置为第一响应者。