Касания начались в UITableViewController

#objective-c #cocoa-touch #uiviewcontroller #uitableview #uiresponder

#objective-c #cocoa-touch #uiviewcontroller #uitableview #пользовательский ответчик

Вопрос:

Я определяю этот метод в своем подклассе UITableViewController:

 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];
    NSLog(@"touch began");
}
  

но это не запускается. UIViewController является подклассом UIResponder, поэтому он должен работать, верно?
Спасибо

Ответ №1:

Если вы пытаетесь отключить клавиатуру в UITableViewController, достойным решением является вызов resignFirstResponder в методе делегата TableView didSelectRowAtIndexPath.

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [myTextField resignFirstResponder];

    // Rest of your actual didSelectRowAtIndexPath code ...
}
  

Комментарии:

1. Эй, у меня была похожая проблема. Из комментариев выше в принятом ответе ясно, что @ sumderungHAY не решил свою проблему, но она все еще принята! Но ваше решение работает для меня!!!

Ответ №2:

Да, это определенно должно сработать.

Убедитесь, что для представления, которому соответствует этот контроллер, включено взаимодействие с пользователем.

Если представление загружается из nib / xib, убедитесь, что для владельца файла установлено соответствующее имя класса, а view выход владельца файла подключен к правильному представлению.

Обновление: я также вижу это поведение, используя приложение, созданное с использованием шаблона приложения на основе навигации, но с шаблоном приложения на основе представления оно работает так, как ожидалось.

Я думаю, что в случае контроллера навигации табличное представление, встроенное в контроллер представления, получает событие раньше, чем это делает контроллер представления. Смотрите ссылку на UIView (выделено мной):

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

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

Не совсем понятно, чего вы пытаетесь достичь, поэтому я не уверен, какое решение предложить.

Комментарии:

1. Привет, спасибо за твой ответ. Я создал новый проект навигации XCode и добавил метод touchesbegan в подкласс UITableViewController (больше ничего не менял), но он не работает

2. Спасибо за ваш подробный ответ. В принципе, у меня есть UITextField типа UIKeyboardTypeNumber pad, и я хочу отказываться от первого ответчика (отклонять клавиатуру) всякий раз, когда пользователь нажимает в любом месте экрана.

3. @zpasternack Я пытаюсь показать что-то на экране, как только пользователь опускает палец на табличное представление, и скрыть это, когда они поднимают палец. Поскольку события не все всплывают из табличного представления, как вы описали, как я могу выполнить то, что я пытаюсь сделать?

Ответ №3:

Я только что столкнулся с точной проблемой, как и при первоначальной публикации. Я решил проблему, создав подкласс UITableView и переопределив метод «touchesBegan». Я также создал протокол, чтобы UITableView мог вызывать метод в UITableViewController, который, в конечном счете, где я хотел обработать событие «touchesBegan».

Вот заголовок для подтипа UITableView:

 @protocol AGSTableViewDelegate;

@interface AGSTableView : UITableView
@property (nonatomic, weak) id<AGSTableViewDelegate> agsDelegate;
@end

@protocol AGSTableViewDelegate<NSObject>
-(void)tableViewTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
@end
  

И реализация:

 @implementation AGSTableView

@synthesize agsDelegate;

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{    
    [super touchesBegan:touches withEvent:event];

    if (agsDelegate)
        [agsDelegate tableViewTouchesBegan:touches withEvent:event];
}
@end
  

И, наконец, фрагменты кода из UITableViewController:

 @interface AGSWasteUpdateTableController ()<AGSTableViewDelegate>
@end

- (void)viewDidLoad
{
    AGSTableView *tableView = (AGSTableView *)[self tableView];
    tableView.agsDelegate = self;
}

-(void)tableViewTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [yourTextField resignFirstResponder];
}
  

Надеюсь, это поможет…

Ответ №4:

Версия Swift, потому что у меня только что была эта самая проблема:

 import UIKit

class BubbleTouchesTableView: UITableView {

    // Designed to bubble up touches from a UITableView

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        super.touchesBegan(touches, withEvent: event)
        self.nextResponder()?.touchesBegan(touches, withEvent: event)
    }

    override func touchesCancelled(touches: NSSet, withEvent event: UIEvent) {
        super.touchesCancelled(touches, withEvent: event)
        self.nextResponder()?.touchesCancelled(touches, withEvent: event)
    }

    override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
        super.touchesEnded(touches, withEvent: event)
        self.nextResponder()?.touchesEnded(touches, withEvent: event)
    }

    override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
        super.touchesMoved(touches, withEvent: event)
        self.nextResponder()?.touchesMoved(touches, withEvent: event)
    }

}
  

Ответ №5:

Вам нужно передать прикосновения вверх по цепочке ответчиков. Мы можем сделать это, создав подкласс UITableView и переопределив touchesBegan (и другие, если необходимо), а затем передав касания вверх по цепочке ответчиков в UITableViewController.

UITableViewTouch.h:

 #import <UIKit/UIKit.h>

@interface UITableViewTouch : UITableView

@end
  

UITableViewTouch.m:

 #import "UITableViewTouch.h"

@implementation UITableViewTouch

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];
    [[self nextResponder] touchesBegan:touches withEvent:event];
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesCancelled:touches withEvent:event];
    [[self nextResponder] touchesCancelled:touches withEvent:event];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesEnded:touches withEvent:event];
    [[self nextResponder] touchesEnded:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesMoved:touches withEvent:event];
    [[self nextResponder] touchesMoved:touches withEvent:event];
}

@end