Сенсорные события на UITableView? - PullRequest
28 голосов
/ 01 мая 2011

У меня UIViewController и UITableView как ребенок в представлении, то, что я хочу сделать, это когда я касаюсь любой строки, я показываю вид снизу. Я хочу скрыть это представление, если пользователь коснется чего-либо еще, кроме строк или нижнего представления.

Проблема в том, что когда я нажимаю UITableView, он не запускает touchesEnded событие.

Теперь, как я могу обнаружить касание на UITableView и отличить его от события выбора строки.

Спасибо.

Ответы [ 7 ]

51 голосов
/ 22 февраля 2013

Нет необходимости создавать подклассы, вы можете добавить UITapGestureRecognizer к UITableView и принять жест или нет в зависимости от ваших критериев.

По вашему мнениюDidLoad:

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapOnTableView:)];
[self.myTableView addGestureRecognizer:tap];

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

-(void) didTapOnTableView:(UIGestureRecognizer*) recognizer {
    CGPoint tapLocation = [recognizer locationInView:self.myTableView];
    NSIndexPath *indexPath = [self.myTableView indexPathForRowAtPoint:tapLocation];

    if (indexPath) { //we are in a tableview cell, let the gesture be handled by the view
        recognizer.cancelsTouchesInView = NO;
    } else { // anywhere else, do what is needed for your case
        [self.navigationController popViewControllerAnimated:YES];
    }
}

И обратите внимание, что если вы просто хотите просто нажимать на щелчки в любом месте таблицы, но не на кнопках в строках ячеек, вам нужно использовать только первый фрагмент кода выше. Типичный пример - когда у вас есть UITableView, а также есть UISearchBar. Вы хотите исключить панель поиска, когда пользователь щелкает, прокручивает и т. Д. Представление таблицы. Пример кода ...

-(void)viewDidLoad {
    [super viewDidLoad];
    etc ...

    [self _prepareTable];
}
-(void)_prepareTable {
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    self.tableView.allowsSelection = NO;
    etc...

    UITapGestureRecognizer *anyTouch =
        [[UITapGestureRecognizer alloc]
         initWithTarget:self action:@selector(tableTap)];
    [self.tableView addGestureRecognizer:anyTouch];
}
// Always drop the keyboard when the user taps on the table:
// This will correctly NOT affect any buttons in cell rows:
-(void)tableTap {
    [self.searchBar resignFirstResponder];
}
// You probably also want to drop the keyboard when the user is
// scrolling around looking at the table. If so:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
    [self.searchBar resignFirstResponder];
}
// Finally you may or may not want to drop the keyboard when
// a button in one cell row is clicked. If so:
-(void)clickedSomeCellButton... {
    [self.searchBar resignFirstResponder];
    ...
}

Надеюсь, это кому-нибудь поможет.

14 голосов
/ 21 июля 2012

Вы должны переслать событие касания в контроллер представления. Создайте подкласс вашего элемента управления tableview и затем переопределите метод:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];  //let the tableview handle cell selection 
    [self.nextResponder touchesBegan:touches withEvent:event]; // give the controller a chance for handling touch events 
}

тогда вы можете делать то, что вы хотите в сенсорных методах контроллера.

8 голосов
/ 22 октября 2011

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

tableView.canCancelContentTouches = NO;

Если для этого параметра не установлено значение NO, сенсорные события отменяются, как только в представлении таблицы появляется небольшое вертикальное движение (еслиесли вы поместите операторы NSLog в свой код, вы увидите, что touchesCancelled вызывается, как только таблица начинает вертикальную прокрутку).

6 голосов
/ 03 августа 2012

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

В моем случае я хочу выбрать строку, в которой будет отображаться какой-либо параметр, после чего я коснусь в любом месте таблицы или View IЯ хочу скрыть эти параметры или выполнить любую задачу, кроме строки, выбранной ранее, для которой я сделал следующее:

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

  2. TableSedSelectRowAtIndexPath выполняет следующие действия:

     - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
        if(indexPath.row != previousSelectedRow && previousSelectedRow != -1) {
            // hide options or whatever you want to do
            previousSelectedRow = -1;
        }
        else {
            // show your options or other things
            previousSelectedRow = indexPath.row;
        }
     }
    

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

Примечание. Код, написанный здесь, может содержать ошибки в написании, потому что он напечатан здесь.:)

3 голосов
/ 27 апреля 2015

Попробуйте следующие методы:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{

}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{

}

Используйте scrollViewDidEndDragging как альтернативу touchesEnded.Надеюсь, это поможет.

2 голосов
/ 01 мая 2011

Для получения сенсорных событий на UITableView используйте:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
  //<my stuff>

  [super touchesBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
   //<my stuff>

   [super touchesMoved:touches withEvent:event];
}

- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
  //<my stuff>

  [super touchesEnded:touches withEvent:event];
}

- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event
{
   //<my stuff>
   [super touchesCancelled:touches withEvent:event];
}

для получения сенсорных событий в UITableView

0 голосов
/ 01 мая 2011

В вашем классе контроллера объявите метод, который удаляет вид снизу.Примерно так:

-(IBAction)bottomViewRemove:(id)sender {

[bottomView removeFromSuperview];

}

В Интерфейсном Разработчике выберите свое представление и в инспекторе идентичности в разделе пользовательского класса измените класс с UIView на UIControl.После этого перейдите в инспектор соединений и подключите событие TouchUpInside к методу, объявленному выше.Надеюсь, это поможет.

...