Uitapgesturerecognizer разрывает UITableView didSelectRowAtIndexPath
Я написал свою собственную функцию для прокрутки текстовых полей вверх, когда появляется клавиатура. Для того, чтобы закрыть клавиатуру, нажав от текстового поля, я создал UITapGestureRecognizer
Это заботится об отставке первого ответчика в текстовом поле при нажатии.
теперь я также создал автозаполнение для текстового поля, которое создает UITableView
чуть ниже текстового поля и заполняет его элементами, когда пользователь вводит текст.
однако, при выборе одного из записи в таблице автозаполнение,didSelectRowAtIndexPath
не вызывали. Вместо этого кажется, что распознаватель жестов крана вызывается и просто уходит в отставку первым ответчиком.
Я предполагаю, что есть какой-то способ сказать распознавателю жестов крана, чтобы продолжать передавать сообщение крана вниз к UITableView
, но я не могу понять, что это такое. Любая помощь будет очень ценится.
15 ответов:
ОК, наконец-то нашел его после некоторого поиска через документы распознавания жестов.
решение было реализовать
UIGestureRecognizerDelegate
и добавить следующее://////////////////////////////////////////////////////////// // UIGestureRecognizerDelegate methods #pragma mark UIGestureRecognizerDelegate methods - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { if ([touch.view isDescendantOfView:autocompleteTableView]) { // Don't let selections of auto-complete entries fire the // gesture recognizer return NO; } return YES; }
Это позаботилось об этом. Надеюсь, это поможет и другим.
самый простой способ решить эту проблему-это:
UITapGestureRecognizer *tapRec = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)]; [tapRec setCancelsTouchesInView:NO];
Это позволяет
UIGestureRecognizer
распознать кран, а также передать прикосновение к следующему ответчику. Непреднамеренное следствие этого метода, если у вас естьUITableViewCell
на экране, который толкает другой контроллер вида. Если пользователь коснется строки, чтобы закрыть клавиатуру, будет распознана как клавиатура, так и нажатие. Я сомневаюсь, что это то, что вы намереваетесь, но этот метод подходит для многих ситуаций.также, расширяя ответ Роберта, если у вас есть указатель на рассматриваемый tableview, то вы можете напрямую сравнить его класс вместо того, чтобы конвертировать в строку и надеяться, что Apple не изменит номенклатуру:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { if([touch.view class] == tableview.class){ return //YES/NO } return //YES/NO }
помните, вы также должны объявить
UIGestureRecognizer
для делегата с этим кодом в нем.
Set
cancelsTouchesInView
вашего распознавателя в false. В противном случае, он" потребляет " прикосновение для себя, а не передает его на вид таблицы. Вот почему событие выбора никогда не происходит.например
swift
let tapOnScreen: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "CheckTheTime") tapOnScreen.cancelsTouchesInView = false view.addGestureRecognizer(tapOnScreen)
и для Swift (на основе ответа от @Jason):
class MyAwesomeClass: UIViewController, UIGestureRecognizerDelegate private var tap: UITapGestureRecognizer! override func viewDidLoad() { super.viewDidLoad() self.tap = UITapGestureRecognizer(target: self, action: "viewTapped:") self.tap.delegate = self self.view.addGestureRecognizer(self.tap) } // UIGestureRecognizerDelegate method func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool { if touch.view?.isDescendantOfView(self.tableView) == true { return false } return true }
возможно, у меня есть лучшее решение, чтобы добавить жест касания над табличным представлением, но одновременно разрешить выбор ячейки:
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool { if gestureRecognizer is UITapGestureRecognizer { let location = touch.locationInView(tableView) return (tableView.indexPathForRowAtPoint(location) == nil) } return true }
Я просто ищу ячейку в точке экрана, где пользователь нажимает. Если путь индекса не найден, я позволяю жесту получить прикосновение, иначе я отменяю его. Для меня это прекрасно работает.
аналогичное решение заключается в реализации
gestureRecognizer:shouldReceiveTouch:
используя класс представления, чтобы определить, какие действия предпринять. Этот подход имеет то преимущество, что не маскирует отводы в области, непосредственно окружающей таблицу (эти представления области все еще происходят от экземпляров UITableView, но они не представляют ячейки).это также имеет бонус, что он работает с несколькими таблицами на одном представлении (без добавления дополнительного кода).
предостережение: есть предположение, что Apple не менять имя.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { return ![NSStringFromClass([touch.view class]) isEqualToString:@"UITableViewCellContentView"]; }
Я думаю, что нет необходимости писать блоки кодов просто установить
cancelsTouchesInView
tofalse
для вашего объекта жест , по умолчанию этоtrue
и вы просто должны установить егоfalse
. Если вы используетеUITapGesture
объект в коде, а также с помощьюUIScrollView
(tableview, collectionview) затем установите это свойствоfalse
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard)) tap.cancelsTouchesInView = false view.addGestureRecognizer(tap)
хотя уже поздно, и многие люди считают, что приведенные выше предложения работают нормально, я не мог заставить методы Джейсона или TMilligan работать.
у меня есть статический tableView с несколькими ячейками, содержащими текстовые поля, которые получают числовые входы, используя только цифровую клавиатуру. Это было идеально для меня:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { if(![touch.view isKindOfClass:[UITableViewCell class]]){ [self.firstTF resignFirstResponder]; [self.secondTF resignFirstResponder]; [self.thirdTF resignFirstResponder]; [self.fourthTF resignFirstResponder]; NSLog(@"Touches Work "); return NO; } return YES; }
убедитесь, что вы реализовали этот
<UIGestureRecognizerDelegate>
в свой .H-файл.эта строка
![touch.view isKindOfClass:[UITableViewCell class]]
проверяет, был ли постучал tableViewCell и отклоняет любую активную клавиатуру.
простое решение-это использование экземпляров UIControl в UITableViewCell для получения касаний. Вы можете добавить любой вид с userInteractionEnables == нет элементов графического интерфейса, чтобы получить кранов.
вот мое решение, которое связывает распознаватель shouldReceiveTouch непосредственно с тем, отображается ли клавиатура.
в вашем делегате распознавателя жестов крана:
#pragma mark - UIGestureRecognizerDelegate - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { if ([PFXKeyboardStateListener sharedInstance].visible) { return YES; } return NO; }
и
PFXKeyboardStateListener.h
:@interface PFXKeyboardStateListener : NSObject { BOOL _isVisible; } + (PFXKeyboardStateListener *)sharedInstance; @property (nonatomic, readonly, getter=isVisible) BOOL visible; @end
и
PFXKeyboardStateListener.m
:static PFXKeyboardStateListener *sharedInstance; @implementation PFXKeyboardStateListener + (PFXKeyboardStateListener *)sharedInstance { return sharedInstance; } + (void)load { @autoreleasepool { sharedInstance = [[self alloc] init]; } } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (BOOL)isVisible { return _isVisible; } - (void)didShow { _isVisible = YES; } - (void)didHide { _isVisible = NO; } - (id)init { if ((self = [super init])) { NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center addObserver:self selector:@selector(didShow) name:UIKeyboardDidShowNotification object:nil]; [center addObserver:self selector:@selector(didHide) name:UIKeyboardWillHideNotification object:nil]; } return self; } @end
вы можете обновить одноэлементный шаблон прослушивателя клавиатуры, я еще не добрался до него. Надеюсь, что это работает для всех остальных, а также это работает для меня. ^^
реализовать этот метод для делегата UIGestureRecognizer:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { UIView *superview = touch.view; do { superview = superview.superview; if ([superview isKindOfClass:[UITableViewCell class]]) return NO; } while (superview && ![superview isKindOfClass:[UITableView class]]); return superview != nil; }
в Swift вы можете использовать это внутри
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { if CheckTheTime() == true { // do something }else{ } } func CheckTheTime() -> Bool{ return true }
мой случай был другим, включая uisearchbar и uitableview на себя.вид. Я хотел отклонить клавиатуру uisearchbar, коснувшись представления.
var tapGestureRecognizer:UITapGestureRecognizer? override func viewWillAppear(animated: Bool) { tapGestureRecognizer = UITapGestureRecognizer(target: self, action:Selector("handleTap:")) }
На UISearchBar Методы Делегата:
func searchBarShouldBeginEditing(searchBar: UISearchBar) -> Bool { view.addGestureRecognizer(tapGestureRecognizer!) return true } func searchBarShouldEndEditing(searchBar: UISearchBar) -> Bool { view.removeGestureRecognizer(tapGestureRecognizer!) return true }
когда пользователь касается себя.вид:
func handleTap(recognizer: UITapGestureRecognizer) { sampleSearchBar.endEditing(true) sampleSearchBar.resignFirstResponder() }
Это мое решение, основанное на ответы выше... Это сработало для меня...
//Create tap gesture for menu transparent view UITapGestureRecognizer *rightTableTransparentViewTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(rightTableTransparentViewTapMethod:)]; [rightTableTransparentViewTap setCancelsTouchesInView:NO]; [_rightTableTransparentView addGestureRecognizer:rightTableTransparentViewTap]; - (void)rightTableTransparentViewTapMethod:(UITapGestureRecognizer *)recognizer { //Write your code here }
вопрос: В моем случае проблема заключалась в том, что я изначально поместил кнопку в каждую ячейку collectionView и установил ограничения для заполнения ячейки, чтобы при нажатии на ячейку она нажимала кнопку, однако функция кнопок была пустой, поэтому ничего не происходило.
исправить: Я исправил это, удалив кнопку из ячейки представления коллекции.