【问题标题】:Overriding method with selector 'touchesBegan:withEvent:' has incompatible type '(NSSet, UIEvent) -> ()'选择器“touchesBegan:withEvent:”的覆盖方法具有不兼容的类型“(NSSet,UIEvent)->()”
【发布时间】:2015-04-30 13:37:57
【问题描述】:

Xcode 6.3。在实现 UITextFieldDelegate 协议的类中,我想覆盖 touchesBegan() 方法以可能隐藏键盘。如果我在函数规范中避免了编译器错误,则尝试从 Set 或 NSSet 读取“触摸”时会出现编译器错误,否则 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' 不符合协议 'Hashable'

试试:

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”

【问题讨论】:

    标签: ios swift overriding


    【解决方案1】:

    Swift 1.2 (Xcode 6.3) 引入了一个原生的 Set 类型来桥接 与NSSet。这在Swift blogXcode 6.3 release notes但显然尚未添加到官方文档中(更新:正如Ahmad Ghadiri noted,它记录在案)。

    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) 更新:(比较 Override func error in Swift 2

    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 并且我的代码正在运行。
    • 嗨@Martin 为什么需要super.touchesBegan(touches , withEvent:event)?我还是不太懂 Swift。
    • 我觉得应该是这样的:xCode 7.2 的 super.touchesBegan(touches, withEvent:event!)
    • @EugeneGordin:你为什么这么认为?最后一种方法仍然可以使用 Xcode 7.2 编译。
    • 它在为我抱怨...可选类型的值未解包
    【解决方案2】:

    对我有用的是:

        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。
    • 你说得对,我今天更新了Xcode,它立即报错。
    【解决方案3】:

    它现在位于 Apple API 参考 here 中,对于 xCode 6.3 版和 swift 1.2 中的覆盖,您可以使用以下代码:

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

    【讨论】:

    • 有趣的是,在线文档是正确的,但是 Xcode 帮助系统中包含的版本已经过时了。我想我需要养成在网上搜索这些东西的习惯。
    【解决方案4】:

    目前的最新版本是 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.
        }
    }
    

    【讨论】:

      【解决方案5】:

      使用 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 函数,获取错误方法不会覆盖其超类中的任何方法。我试图从UIGestureRecognizerUTapGestureRecognizer 继承。 Xcode 7.1
      • 使用这个stackoverflow.com/questions/30892254/…来检查你的代码发生了什么
      【解决方案6】:

      少量添加。为了快速编译无错误,您需要添加

      导入 UIKit.UIGestureRecognizerSubclass

      【讨论】:

        【解决方案7】:

        使用 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>
        }
        

        【讨论】:

          【解决方案8】:

          使用 Swift 4Xcode 9

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

          【讨论】:

            【解决方案9】:
              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)
                        }
                    }
                }
            

            【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-04-18
            • 1970-01-01
            • 1970-01-01
            • 2012-01-17
            • 1970-01-01
            • 1970-01-01
            • 2018-07-26
            相关资源
            最近更新 更多