Как я могу сказать, когда что-то вне моего UITableViewCell было затронуто? - PullRequest
4 голосов
/ 15 марта 2010

Аналогично этот вопрос У меня есть собственный подкласс UITableViewCell, который имеет UITextField. Он отлично работает, за исключением клавиатуры, которая не исчезает, когда пользователь касается другой ячейки табличного представления или чего-либо вне таблицы. Я пытаюсь найти лучшее место, чтобы узнать, когда что-то находится вне ячейки, а затем я могу вызвать resignFirstResponder для текстового поля.

Если бы UITableViewCell мог получать события касания для касаний вне его представления, то он мог бы просто сам resignFirstResponder, но я не вижу способа получить эти события в ячейке.

РЕДАКТИРОВАТЬ: Я пытался это (ниже) в моем подклассе UITableViewCell, но это не работает, я думаю, потому что touchesBegan: withEvent: не вызывается, если событие было обработано контроль. Я думаю, что мне нужно перехватить события, прежде чем они каким-то образом отправят цепочку респондента.

Решение, которое я рассматриваю, заключается в добавлении метода touchesBegan: withEvent: в контроллер представления. Там я мог бы отправить resignFirstResponder всем видимым ячейкам таблицы, кроме той, в которой было касание (пусть оно получает событие касания и обрабатывает его само).

Может быть, что-то вроде этого псевдокода:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    CGPoint touchPoint = // TBD - may need translate to cell's coordinates

    for (UITableViewCell* aCell in [theTableView visibleCells]) {
        if (![aCell pointInside:touchPoint withEvent:event]) {
             [aCell resignFirstResponder];
        }
    }
}

Я не уверен, что это лучший способ сделать это. Похоже, что сама ячейка просмотра таблицы никак не может получать уведомления о событиях за ее пределами.

EDIT2: Я думал, что у меня есть ответ (я даже опубликовал его как ответ), используя hitTest: withEvent:, но это не сработало. Это не всегда называют. : - (

Ответы [ 3 ]

10 голосов
/ 16 марта 2010

[Отредактировано: удалена предыдущая попытка, которая не всегда работала, эта работает]

ОК, я наконец нашел решение, которое полностью работает. Я создал подкласс UITableView и переопределил метод hitTest: withEvent: Он вызывается для всех касаний в любом месте табличного представления, единственные другие возможные касания находятся на панели навигации или клавиатуре, и hitTest табличного представления не должен знать о них.

Это отслеживает активную ячейку в табличном представлении, и всякий раз, когда вы нажимаете на другую ячейку (или не ячейку), она отправляет resignFirstResponder в ячейку, которая становится неактивной, что дает ей возможность скрыть свою клавиатуру (или ее DatePicker).

-(UIView*) hitTest:(CGPoint)point withEvent:(UIEvent*)event
{
    // check to see if the hit is in this table view
    if ([self pointInside:point withEvent:event]) {
        UITableViewCell* newCell = nil;

        // hit is in this table view, find out 
        // which cell it is in (if any)
        for (UITableViewCell* aCell in self.visibleCells) {
            if ([aCell pointInside:[self convertPoint:point toView:aCell] withEvent:nil]) {
                newCell = aCell;
                break;
            }
        }

        // if it touched a different cell, tell the previous cell to resign
        // this gives it a chance to hide the keyboard or date picker or whatever
        if (newCell != activeCell) {
            [activeCell resignFirstResponder];
            self.activeCell = newCell;   // may be nil
        }
    }

    // return the super's hitTest result
    return [super hitTest:point withEvent:event];   
}    

В моих подклассах UITableViewCell, которые имеют UITextField, я добавляю следующий код, чтобы избавиться от клавиатуры (или средства выбора даты, которое скользит как клавиатура):

-(BOOL)resignFirstResponder
{   
    [cTextField resignFirstResponder];  
    return [super resignFirstResponder];
}

Ура!

0 голосов
/ 11 августа 2010

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

0 голосов
/ 16 марта 2010

Я думаю, что вы на правильном пути, но touchesBegan:withEvent: - это метод UIResponder, так что вам действительно придется переопределить его в подклассе UIView, а не в вашем подклассе UIViewController. Ваши варианты:

  • Если вы уже создаете подкласс UITableViewCell, переопределите touchesBegan:withEvent: там.
  • Если вы используете стандартный UITableViewCell, внедрите tableView:didSelectRowAtIndexPath в делегат вашего UITableView.
...