Существует несколько способов устранить эту проблему. То, что происходит, - то, что tableViewCell делегирует сенсорное событие к своим подпредставлениям, которое заставляет текстовое поле обрабатывать касание в земельном участке Вашей ячейки.
Для фиксации этого:
Набор userinteractionEnabled свойство UITEXTFIELD к нет, тогда когда Вы получаете сообщение didSelectRowAtIndexPath, Вы повторно включаете userInteractionEnabled и называете becomeFirstResponder TextField. На v2.2 Вы не должны даже устанавливать флаг userInteractionEnabled, я не протестировал это с другими версиями однако, документация является довольно четкой, что необходимо включить это. в tableViewController просто необходимо было сохранить indexpath, пока Вы не добираетесь, сообщение
UIKeyboardDidShow Создают делегата к UITextField, который сообщает Вашему tableViewController так, чтобы можно было установить смещение прокрутки оттуда.
регистр для событий клавиатуры и затем выясняет scrolloffset путем проверки того, какое текстовое поле находится в режиме редактирования
Можно установить контроллер как делегат UITextField, затем скорректировать табличное представление или в textFieldDidBeginEditing:
или в textFieldShouldBeginEditing:
Регистр для UIKeyboardWillShowNotification и UIKeyboardWillHideNotification, затем скорректируйте свое представление по мере необходимости в обработчиках уведомлений. Одно из приложений в качестве примера показывает, как сделать это, но я забываю который... SQLiteBooks или возможно EditableDetailView.
Я боролся с той же проблемой, когда у меня есть UITextFields внутри UITableViewCells, и я не мог получить представление для прокрутки к полю, когда оно редактировалось. Суть моего решения ниже.
Ключом к этому коду является строка, в которой создается UITextField. Вместо жесткого кодирования значений ax и y в функции CGRectMake () он использует x и y из ячейки, в которую они помещаются (+/- любое смещение, которое вы хотите от краев ячейки, как показано ниже). Жесткое кодирование значений x и y в UITextField * дает каждой ячейке одинаковую x, y позицию кадра для каждого UITextField * (по-видимому, оно переопределяется рамкой ячеек при его отображении), поэтому, когда вы вызываете 'scrollRectToVisible 'код, похоже, не имеет правильных координат, до которых он должен прокручиваться.
1) создать ячейку, и добавьте UITextField * в ячейку, используя значения x и y фрейма ячейки (я включаю сюда смещения, которые являются необязательными
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell* cell;
cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"UITableViewCell"] autorelease];
//this is the critical part: make sure your UITextField* frame is based on the frame of the cell in which it's being placed.
UITextField* txtField = [[UITextField alloc] initWithFrame:CGRectMake(cell.frame.origin.x+20, cell.frame.origin.y+9, 280, 31)];
txtField.delegate = self;
[cell addSubview:txtField];
return cell;
}
2). Отрегулируйте вид прокрутки в textFieldDidBeginEditing
-(void) textFieldDidBeginEditing:(UITextField *)textField {
CGRect textFieldRect = [textField frame];
[self.tableView scrollRectToVisible:textFieldRect animated:YES];
}
Я не нашел в Интернете подходящих для меня решений. После нескольких дней поисков в Google и экспериментов я, наконец, хорошо продумал этот вопрос. Это сложная ошибка в Apple iPhone, как вы увидите в конце этого поста.
Если вы столкнулись с такой же проблемой, как я, а именно:
наличие ячейки tableviewcell, превышающей половину экрана iphone (не путать с примерами Apple UICatalog, у которых есть короткая ячейка tableview менее 50 пунктов, здесь неприменимо) ,
наличие более одного uitexfields в ячейке или комбинация uitextfield и uitextview или uiwebview в ячейке,
Нажатие между uitextfields и uitextview или uiwebview приводит к непредсказуемой позиции прокрутки, либо выделенное поле uitext выскакивает из поля зрения, либо закрывается клавиатура. Он работает только в первый раз, когда клавиатура появляется в ячейке tableview и впоследствии перестает работать правильно.
У меня был серьезный прорыв после прочтения постов, похожих на этот: http://alanduncan.net/old/index.php?q=node/13 Они тоже не поняли полностью . Боль вызвана ошибкой в событиях UIKeyboard. Когда клавиатура впервые появляется, она выдает UIKeyboardWillShowNotification и UIKeybaordDidShowNotification. Это ошибка в iPhone, которая каким-то образом отличается от первого UIKeyboardWillShowNotification от последующего UIKeyboardWillShowNotification. Решение - НАБЛЮДАТЬ UIKeyboardDidShowNotification. Поэтому, когда ваша ячейка появится, добавьте следующий код
NSNotificationCenter*nc=[NSNotificationCenter defaultCenter];
[nc addObserver:self selectorselector(keyboardDidShow name:UIKeyboardDidShowNotification object:self.window];
. В функции keyboardDidShow нам нужно прокрутить TABLEVIEW, а не tableviewcell, как предложено в сообщении выше. Или вы можете увидеть, как разные объекты идут по отдельности, а не скручиваются вместе как одно целое.
(void)keyboardDidShow:(NSNotification *)notif
{
//1. see which field is calling the keyboard
CGRect frame;
if([textField_no1 isFirstResponder])
frame=textField_no1.frame;
else if([textField_no2 isFirstResponder])
frame=textField_no2.frame;
else if([textField_no3 isFirstResponder])
frame=textField_no3.frame;
else if([textView isFirstResponder])
frame=textView.frame;
else return;
CGRect rect=self.superview.frame;
//2. figure out how many pixles to scroll up or down to the posistion set by theKeyBoardShowUpHorizon.
//remove the complexity when the tableview has an offset
[((UITableView*)[self.superview).setContentOffset:CGPointMake(0,0) animated:YES];
int pixelsToMove=rect.origin.y+ frame.origin.y-theKeyBoardShowUpHorizon;
//3. move the uitableview, not uitableviewcell
[self moveViewUpOrDownByPixels:pixelsToMove];
}
- (void)moveViewUpOrDownByPixels:(int)pixels
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.6];
//find the position of the UITableView, the superView of this tableview cell.
CGRect rect=self.superview.frame;
//moves tableview up (when pixels >0) or down (when pixels <0)
rect.origin.y -= pixels;
rect.size.height += pixels;
self.superview.frame = rect;
[UIView commitAnimations];
}
Чтобы восстановить tableView обратно, вам нужно добавить наблюдателя в UIKeyboardDidHideNotification (не UIKeyboardWillHideNotification, как предлагается в других сообщениях, чтобы избежать мерцания), где tableviewcell появляется каждый раз и возвращает tableview туда, где оно было.
[nc addObserver:self selectorselector(keyboarDidHide) name:UIKeyboardDidHideNotification object:nil];
- (void)keyboardDidHideNSNotification*)notif
{
//we have moved the tableview by number of pixels reflected in (self.superview.frame.origin.y). We need to move it back
[self moveViewUpOrDownByPixels:self.superview.frame.origin.y];
}
Не забудьте удалить обоих наблюдателей, когда ваша ячейка исчезнет с помощью [[NSNotificationCenter defaultCenter] removeObserver: ...
Это все, что нужно. Я надеюсь, что команда Apple iPhone однажды решит эту проблему, может быть, в 4.0 через несколько месяцев.