2

谁能帮我这个?

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.delegate=self
    tableView.dataSource=self
    searchBar.autocorrectionType = .yes
    searchBar.delegate=self
    searchBarView.translatesAutoresizingMaskIntoConstraints=false

    let tap:UIGestureRecognizer = UITapGestureRecognizer(target: self, action: Selector(("tapCancel:")))

    searchBarView.addGestureRecognizer(tap)
    tableView.addGestureRecognizer(tap)
    tableView.isUserInteractionEnabled=true
}
...
func tapCancel(sender:UITapGestureRecognizer){
    hideSearchBarView()
    isSearchon=false
    print("Tap cancel!")
}

每次我点击视图时,它都会崩溃。“无法识别的选择器发送到实例 0x7feb85d109e0”

我将不胜感激任何帮助!谢谢!

4

2 回答 2

2

我相信原因是由于方法名称在 Swift 和 Objective-C 之间的映射方式,这是 Cocoa 实现和整个目标/动作机制的基础。

在您的情况下,Swift 方法

@objc func tapCancel(sender:UITapGestureRecognizer)

...对应于Objective-C 选择器

-tapCancelWithSender:

注意:为了使用目标/动作范例(即,通过选择器调用),该方法需要声明为@objc. 替代属性@IBOutlet(与 Interface Builder 一起使用)也支持这一点。(向@rmaddy 致敬)

为了删除 "withSender" 部分并获得匹配的选择器tapCancel:,您需要告诉 Swift 删除参数 label sender,如下所示:

func tapCancel(_ sender:UITapGestureRecognizer) // Notice the underscore (_)

此外,根据@dan 的评论,也许您可​​以使用:

#selector(self.tapCancel(_:))

或更简洁地说,正如(再次感谢)@rmaddy 所指出的那样,只是:

#selector(tapCancel)

(Xcode 会尝试将其自动补#selector(tapCancel(_:))全为

我不熟悉Selector()你使用的语法,所以我试着玩了一下,瞧:

在此处输入图像描述 (选择器不匹配编译器可以“看到”的任何方法)。

在此处输入图像描述 (添加“withSender”后,编译器可以匹配该方法,但建议使用更好的#selector(...语法)。

正如@rmaddy 在评论中指出的那样,使用较短的#selector(doSomething)语法(没有冒号、没有下划线、没有self)也可以解决是否需要“withSender”的问题。

于 2018-06-19T03:43:39.960 回答
0

利用

let tap:UIGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapCancel))

代替

let tap:UIGestureRecognizer = UITapGestureRecognizer(target: self, action: Selector(("tapCancel:")))

并添加@objcbefore 方法tapCancel()

于 2018-06-19T05:42:01.650 回答