it-swarm.com.ru

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

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

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

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

в мой метод делегата tableView и в мой метод делегата UITextFieldtextFieldDidBeginEditing:.

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

19
Coocoo4Cocoa

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

- (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];
}
22
Friggles

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

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

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

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

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

9
terra

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

6
August

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

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

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

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

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

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

  1. Откройте файл .xib в конструкторе интерфейсов.
  2. Выберите вид таблицы
  3. В меню IB выберите "Инструменты" -> "Инспектор размеров". В разделе "Размер представления прокрутки" измените Вкладка -> Нижнее значение на 100, 150, 250 в зависимости от размера представления таблицы.

код

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

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

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

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

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

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

У меня был серьезный прорыв после прочтения постов, похожих на этот: http://alanduncan.net/old/index.php?q=node/1 Они тоже не совсем поняли это правильно. Боль вызвана ошибкой в ​​событиях UIKeyboard. Когда клавиатура появляется впервые, она выдает UIKeyboardWillShowNotification и UIKeybaordDidShowNotification. Theree - это ошибка в iPhone, которая так или иначе первая UIKeyboardWillShowNotification отличается от последующей UIKeyboardWillShowNotification. Решение - НАБЛЮДАТЬ UIKeyboardDidShowNotification. Поэтому, когда ваша ячейка появится, добавьте следующий код

 NSNotificationCenter*nc=[NSNotificationCenter defaultCenter];
    [nc addObserver:self selectorselector(keyboardDidShow name:UIKeyboardDidShowNotification object:self.window];

В функции keyboardDidShow нам нужно прокручивать TABLEVIEW, а не ячейку просмотра таблицы, как предложено в посте выше. Или вы можете видеть, как различные объекты идут по-разному, а не прокручиваются вместе одним куском.

(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, как это предлагается в других публикациях, чтобы избежать мерцания), где ячейка 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 через несколько месяцев.

3
Wayne Lo

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 к себе

1
Ramesh

Я боролся с той же самой проблемой, где у меня есть 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'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];
}
0
user119541

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

0
Brandon Fosdick

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

0
Narayana

Проблема усугубляется тем, что нет простого способа узнать, нажал ли пользователь текстовое поле или оно было активировано с помощью 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];
}
0
highmaintenance