使用选择器'touchesBegan:withEvent:'的重写方法具有不兼容的类型'(NSSet,UIEvent)->()'


77

Xcode 6.3。在实现UITextFieldDelegate协议的类中,我想重写touchesBegan()方法以可能隐藏键盘。如果我避免函数规范中的编译器错误,则尝试从Set或NSSet读取“ touch”时会出现编译器错误,否则super.touchesBegan(touches,withEvent:event)会引发错误。这些组合之一是在Xcode 6.2中编译的!(因此,Swift“ Set”的文档在哪里以及如何从其中获取元素?)

 override func touchesBegan(touches: NSSet, withEvent event: UIEvent) { 
    // Hiding the Keyboard when the User Taps the Background
        if let touch =  touches.anyObject() as? UITouch {
            if nameTF.isFirstResponder() && touch.view != nameTF {
                nameTF.resignFirstResponder();
            }
        }
        super.touchesBegan(touches , withEvent:event)
    }

尝试:

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) or
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent) 

编译器错误:具有选择器'touchesBegan:withEvent:'的重写方法具有不兼容的类型'(NSSet,UIEvent)->()',并且

super.touchesBegan(touches , withEvent:event)

也抱怨

“ NSSet”不能隐式转换为“ Set”;您是说要使用“ as”进行显式转换吗?

尝试:

override func touchesBegan(touches: Set<AnyObject>, withEvent event: UIEvent) 

编译器错误:类型“ AnyObject”不符合协议“哈希”

尝试:

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) 

编译器错误

if let touch = touches.anyObject() as? UITouch 

'Set'没有名为'anyObject'的成员,但函数规范和对super()的调用都可以!

尝试:

override func touchesBegan(touches: NSSet<AnyObject>, withEvent event: UIEvent) -> () or
override func touchesBegan(touches: NSSet<NSObject>, withEvent event: UIEvent) 

编译器错误:无法专用于非通用类型“ NSSet”

Answers:


161

Swift 1.2(Xcode 6.3)引入了Set与桥接的本机类型NSSetSwift博客Xcode 6.3发行说明中都提到了这一点,但显然尚未将其添加到官方文档中(更新:正如Ahmad Ghadiri所指出的,现在记录在案)。

UIResponder方法现在声明为

func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent)

您可以像这样覆盖它:

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    if let touch = touches.first as? UITouch {
        // ...
    }
    super.touchesBegan(touches , withEvent:event)
}

Swift 2(Xcode 7)更新:(比较Swift 2中的Override Func错误

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    if let touch = touches.first {
        // ...
    }
    super.touchesBegan(touches, withEvent:event)
}

Swift 3更新:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        // ...
    }
    super.touchesBegan(touches, with: event)
}

感谢Martin R,我要做的就是将我的NSSet更改为Set <NSObject>,并且我的代码正在运行。
MwcsMac 2015年

1
您好@Martin为什么 super.touchesBegan(touches , withEvent:event)需要?我仍然对Swift不太了解。
Zigii Wong 2015年

我觉得它应该是这样的:xCode 7.2的super.touchesBegan(touches,withEvent:event!)
Eugene Gordin

@EugeneGordin:你为什么这么认为?最后一种方法仍然可以使用Xcode 7.2进行编译。
Martin R

它在为我抱怨...可选类型的值
未解

10

对于xCode 7和swift 2.0,请使用以下代码:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

    if let touch =  touches.first{
        print("\(touch)")
    }
    super.touchesBegan(touches, withEvent: event)
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {

    if let touch = touches.first{
        print("\(touch)")
    }
    super.touchesEnded(touches, withEvent: event)
}

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {

    if let touch = touches.first{
        print("\(touch)")
    }
    super.touchesMoved(touches, withEvent: event)
}

我无法建立专案。得到错误的方法不会覆盖从其超的任何方法touchesBegan功能。我试图从UIGestureRecognizer和继承UTapGestureRecognizer。Xcode 7.1
Boris Y. 2015年


10

使用Swift 3Xcode 8

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

}

override func touchesCancelled(_ touches: Set<UITouch>?, with event: UIEvent?) {
// Don't forget to add "?" after Set<UITouch>
}

6

现在可以在Apple API参考中找到它,并且要在xCode版本6.3和Swift 1.2中进行覆盖,可以使用以下代码:

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    if let touch =  touches.first as? UITouch {
         // ...
    }
    // ...
}

有趣的是,在线文档是正确的,但Xcode帮助系统中包含的版本已过时。我想我需要养成在网上搜索这些东西的习惯。
Duncan C

6

2015年12月19日的xCode 7.2 Swift 2.1的最新更新的当前版本。

下次再次遇到这样的错误时,请删除该函数,然后再次在“ touchesBe ...”中键入该函数,xCode应该会自动为您完成最新的功能,而不是尝试修复旧的功能。

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {

    for touch: AnyObject! in touches {
        let touchLocation = touch.locationInNode(self)

        //Use touchLocation for example: button.containsPoint(touchLocation) meaning the user has pressed the button.
    }
}

4

对我有用的是:

    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        if let touch = touches.first as? UITouch {
            // ...
        }

        super.touchesBegan(touches , withEvent:event!)
    }

如果您使用的是Xcode 6.3和Swift 1.2,则您的代码将无法正常工作。如果引用Xcode 6.3和Swift 1.2,则为这篇文章。
MwcsMac 2015年

1
没错,我今天更新了Xcode,它立即产生了错误。
jfredsilva 2015年

4

小加成。为了迅速编译没有错误,您需要添加

导入UIKit.UIGestureRecognizerSubclass


1

使用Swift 4Xcode 9

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

}

0
  override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        if let touch = touches.first as? UITouch {

            if touch.view == self.view{
                self.dismiss(animated: true, completion: nil)
            }
        }
    }

2
添加评论,解释您的答案,阅读如何回答
Aksen P
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.