在我的應用程序中,我填寫了一個很大的表單。表單本身是由表格視圖和靜態單元格模式構成的。每個單元格都包含一個標籤和一個文本框。我想在鍵盤上添加一個工具欄來啓用文本字段之間的導航。我這樣做了,但它表現得很奇怪(至少我認爲)。iOS 5:在TextFields之間跳躍時的奇怪行爲
跳轉到下一個文本字段時跳轉到前一個文本字段是沒有問題的,只有在可見時纔可以。如果它不可見,舊的textfield保持第一響應者,但是當我滾動我的表格視圖和想要的文本字段變得可見時,它成爲第一響應者(我沒有點擊它!)。那當然不是我想要的行爲。
我的問題是:這種行爲是否正常?你能以某種方式規避它嗎?
如果你想親自看到這種行爲,我已經上傳了一個說明問題的Xcode項目。你可以在這裏下載壓縮項目:download。代碼的主要部分如下所述。
我使用靜態單元設置了分組表格視圖。其中每個包含一個標籤和一個textfield
。我爲每個文本字段創建了插件以訪問它們。在我的viewDidLoad方法中,我創建工具欄及其按鈕,將文本字段存儲在數組中,並將控制器設置爲文本字段委託。
- (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];
}
謝謝!
您是否嘗試在更改第一個響應者之前滾動表格視圖以使前一個單元格可見? – dasdom
感謝@dasdom和rob。我應該提到我嘗試過。問題是如果cell不可見,indexPathForCell返回null。在我的應用程序中,不是每行都包含一個文本框,所以我必須跟蹤其他位置的位置。它當然有效,但我認爲這不是一個理想的解決方案。 – patman