UITextView专注,但用户触摸UICollectionViewCell。隐藏键盘并运行didSelectItemAtIndexPath

时间:2015-04-09 05:04:15

标签: ios swift uitextfield

我在我的视图顶部有一个“搜索”UITextField。 在此之下,我有一个UICollectionView,它在用户输入时用搜索结果填充。

当用户在UITextView中输入内容时,会显示键盘。首先,如果用户触摸UITextField之外的任何地方,我想隐藏键盘。我用以下内容完成了这个:

func textFieldDidBeginEditing(textField: UITextField) {

    if (textField == self.textFieldSearch) {
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "textFieldSearchDidChange:", name: UITextFieldTextDidChangeNotification, object: textField)
    }

    var tapGesture = UITapGestureRecognizer(target: self, action: "dismissKeyboard:")
    self.view.addGestureRecognizer(tapGesture)

}

func dismissKeyboard(gesture: UIGestureRecognizer) {
    self.textFieldSearch.resignFirstResponder()
    self.view.removeGestureRecognizer(gesture)
}

但是,如果用户点击UICollectionViewCell,则dismissKeyboard func会运行,并隐藏键盘,但用户必须再次点击该单元格来运行func:

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {

如何一步到位?因此,如果用户触摸UITextField之外的任何地方,则隐藏键盘...但如果用户碰巧触摸UICollectionViewCell,请在第一次触摸时运行didSelectItemAtIndexPath功能,并隐藏键盘并在UITextField上结束编辑?

任何帮助表示赞赏! 感谢

5 个答案:

答案 0 :(得分:1)

请尝试这个

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
        if touch.view == self.textFieldSearch{
            return false;
        }
        else{
            return true;
        }
    }

并在代码中添加此行

var tapGesture = UITapGestureRecognizer(target: self, action: "dismissKeyboard:")
tapGesture.delegate = self // add gesture delegate here 
    self.view.addGestureRecognizer(tapGesture)

答案 1 :(得分:1)

您可以实现UIGestureRecognizerDelegate

的委托方法
optional func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
             shouldReceiveTouch touch: UITouch) -> Bool

上面的方法为不应该调用手势识别器的视图返回NO,在你的情况下它应该是集合视图,否则返回YES。

示例实现 -

/**
    Disallow recognition of tap gestures on the collection view.
*/
    func gestureRecognizer(recognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool 
{
        if touch.view == collectionView && recognizer == tapRecognizer     {
            return false
        }
        return true
 }

答案 2 :(得分:0)

这是一个解决方案。有点janky但它应该做的伎俩。你可能不得不修补一下。此外,我的Swift并不是顶级的,所以请原谅任何语法错误。

func dismissKeyboard(gesture: UIGestureRecognizer) {
    let point : CGPoint = gesture.locationInView(self.collectionView)
    let indexPath : NSIndexPath = self.collectionView.indexPathForItemAtPoint(point)

    self.textFieldSearch.resignFirstResponder()
    self.view.removeGestureRecognizer(gesture)

    self.collectionView.selectItemAtIndexPath(indexPath, animated:YES, scrollPosition:UICollectionViewScrollPosition.Top)
}

答案 3 :(得分:0)

我在这里提供一个Objective-C代码,用于在外部执行的任何触摸上关闭keyBoard。请亲自为Swift写一下。问题是你正在添加一个隐藏收集单元的触摸事件的轻拍手势。

因此,使用以下代码的Swift翻译代码,而不是点击手势。

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.view endEditing:YES];
}

请勿使用您的点按手势。我认为事情应该适合你...

修改

为swift编写上述代码的一些努力...

override func touchesBegan(touches: NSSet, withEvent event: UIEvent){

    self.view.endEditing(true)

}

答案 4 :(得分:0)

在上面的@Sanjay的帮助下,这个代码终于完成了。 如果用户触摸了未被单元格占用的collectionView部分,我仍然想要隐藏键盘。如果用户“滑动/滚动/拖动”,我仍然需要实现隐藏键盘的代码。在UICollectionView而不是点击。

目前:

func gestureRecognizer(recognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {

    for cell:AnyObject in self.collectionView.visibleCells() {
        if (touch.view.isDescendantOfView(cell as UIView)) {
            self.resignAllResponders()
            return false
        }
    }

    return true

}