Подтвердить что ты не робот

Нажатие на UITextField в UITableViewCell

У меня проблема, когда при нажатии textField в UITableViewCell метод tableView:didSelectRowAtIndexPath: не запускается. Проблема в том, что мне нужно прокрутить мой tableView в правильное положение, иначе клавиатура будет идти прямо над первым ответчиком.

Затем я должен переместить код следующим образом:

[[self tableView] scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];

как в моем методе делегата tableView, так и в методе делегата UITextField, textFieldDidBeginEditing:.

Является лучшим способом просто создать новый метод, передать ему индексную ячейку ячейки/текстового поля и вызвать метод как из делегата tableView, так и из делегата UITextField? лучший способ обойти это?

4b9b3361

Ответ 1

Я нашел следующие работы хорошо (предполагается, что вы находитесь в контроллере табличного представления)

- (void)textFieldDidBeginEditing:(UITextField *)textField{  
    CGPoint pnt = [self.tableView convertPoint:textField.bounds.origin fromView:textField];
    NSIndexPath* path = [self.tableView indexPathForRowAtPoint:pnt];
    [self.tableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

Ответ 2

Есть несколько способов решить эту проблему. Что происходит, так это то, что tableViewCell делегирует событие касания к его подзонам, что заставляет текстовое поле обрабатывать касание вместо вашей ячейки.

Чтобы исправить это:

  • Задайте для свойства userinteractionEnabled для UITextfield значение НЕТ, а затем, когда вы получите сообщение didSelectRowAtIndexPath, вы снова включите userInteractionEnabled и вызовите TextField, чтобы получить FirstResponder. На v2.2 вам даже не нужно устанавливать флаг userInteractionEnabled, я не тестировал его с другими версиями, однако в документации достаточно ясно, что вы должны включить это. в tableViewController вам просто нужно сохранить индексный путь до тех пор, пока вы не получите сообщение UIKeyboardDidShow

  • Создайте делегат для UITextField, который отправляется обратно в ваш tableViewController, чтобы вы могли установить смещение прокрутки.

  • зарегистрируйтесь для событий клавиатуры, а затем выясните прокрутку, проверив, какое текстовое поле находится в режиме редактирования.

Ответ 3

Вы можете установить ваш контроллер в качестве делегата вашего UITextField, а затем настроить представление таблицы в textFieldDidBeginEditing: или textFieldShouldBeginEditing:

Ответ 4

Я не нашел решений, которые работают для меня в Интернете. После нескольких дней работы в Google и экспериментов я, наконец, получил это хорошо. Это сложная ошибка в Apple iPhone, как вы увидите в конце этого сообщения.

Если вы столкнулись с проблемой, подобной мне, следующим образом:

  1. у которого tableviewcell больше половины экрана iphone (не путайте с примерами Apple UICatalog, у них есть короткая ячейка tableview менее 50 пунктов, здесь не применимо.),

  2. имеющий более одного поля uitex в ячейке или комбинацию uitextfield и uitextview или uiwebview в ячейке,

  3. Нажатие между uitextfields и uitextview или uiwebview приводит к непредсказуемой позиции прокрутки, либо щелкнуло uitextfield, которое выпрыгивает из поля зрения или покрывается keybaord. Он работает только в первый раз, когда клавиатура появляется в tableviewcell и не работает в дальнейшем.

У меня был большой прорыв после чтения сообщений, похожих на этот: http://alanduncan.net/old/index.php?q=node/13 Они тоже не поняли. Боль вызвана ошибкой в ​​событиях UIKeyboard. Когда клавиатура сначала появляется, она выдает UIKeyboardWillShowNotification и UIKeybaordDidShowNotification. Theree - ошибка в 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];
}

Чтобы восстановить таблицуView назад, вам нужно добавить наблюдателя в UIKeyboardDidHideNotification (а не UIKeyboardWillHideNotification, как было предложено другими сообщениями, чтобы избежать мерцания), где вы каждый раз видите tableviewcell и возвращаете табличное представление туда, где оно было.

[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 через несколько месяцев.

Ответ 5

Я нашел решение.

  • Откройте файл .xib в построителе интерфейсов.
  • Выберите представление таблицы
  • Из меню IB выберите Tools- > Size Inspector В разделе "Размер прокрутки" измените Вставить → Нижнее значение на 100, 150, 250 в зависимости от того, насколько велик ваш табличный вид.

код

-(void) textFieldDidBeginEditing:(UITextField *)textField 
{
    UITableViewCell *cell = (UITableViewCell *) [[textField superview] superview];
    [self.tableView scrollToRowAtIndexPath:[tableView indexPathForCell:cell]
    atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}

Ответ 6

Я обнаружил, что на самом деле это довольно легко сделать.

Метод делегата UITextField textFieldDidBeginEditing предоставит вам текстовое поле, которое затем можно сопоставить с indexPath, используя:

self.currentIndexPath = [self.tableView indexPathForRowAtPoint:textField.frame.origin];

Затем вы можете прокрутить ячейку в виде (т.е. в вашем обработчике уведомлений клавиатуры UIKeyboardDidShowNotification):

[self.tableView scrollToRowAtIndexPath:self.currentIndexPath atScrollPosition:UITableViewScrollPositionNone animated:YES];

Ответ 7

didSelectRowAtIndexPath не будет вызываться для встроенных ячеек UITextField; следовательно, логика прокрутки должна быть в другом месте.

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:1];
    UITableViewCell *cell = [_tableView cellForRowAtIndexPath:indexPath];
    [_tableView setContentOffset:CGPointMake(0, cell.frame.size.height) animated:YES];
}

Удостоверьтесь, что текстовый делегат textField включен

Ответ 8

Зарегистрируйтесь для UIKeyboardWillShowNotification и UIKeyboardWillHideNotification, а затем настройте свое представление по необходимости в обработчиках уведомлений. Один из примеров приложений показывает, как это сделать, но я забыл, какие... SQLiteBooks, или, возможно, EditableDetailView.

Ответ 9

Я боролся с этой же проблемой, где у меня UITextFields внутри UITableViewCells и не смог получить представление для прокрутки к полю при его редактировании. Ядро моего решения ниже.

Ключ к этому коду - это строка, в которой создается UITextField. Вместо жесткого кодирования значения x и 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 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];
}

Ответ 10

Проблема усугубляется тем фактом, что нет простого способа узнать, прослушивал ли пользователь текстовое поле или активировался через becomeFirstResponder.

Самое элегантное решение, которое я мог придумать, заключалось в том, чтобы реализовать подкласс hitTest:withEvent: в ядре и в основном делать вид, что текстовое поле не существует, пока не будет выбрана ячейка.

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    UIView *view = [super hitTest:point withEvent:event];

    if(view == self.textField && !self.selected) {
        return self;
    }

    return view;
}

tableView:didSelectRowAtIndexPath:, тогда необходимо вручную сделать текстовое поле первым ответчиком.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    TextFieldCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];

    [cell.textField becomeFirstResponder]

    [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

Наконец, мы должны отменить выбор строки, когда закончим редактирование. Это можно сделать с помощью делегата UITextField или с помощью уведомления о клавиатуре, независимо от того, что вы предпочитаете.

- (void)textFieldDidEndEditing:(UITextField *)textField {
   [self.view endEditing:YES];
}

Ответ 11

у нас есть один контроллер под названием TPKeyboardAvoiding, он обрабатывает все, что касается динамической автоматической прокрутки для tableview и scrollview. вы можете загрузить образец кода из кода ниже. https://github.com/NarayanaRao35/TPKeyboardAvoiding