Swift 枚举到 Cocoa Touch UIButton 选择器字符串
Swift Enum to Cocoa Touch UIButton selector string
我正在为我的 letterTapped()
函数向 UIButton 添加一个目标,如下所示:
button.addTarget(self, action: "letterTapped:", forControlEvents: .TouchUpInside)
我喜欢 .TouchUpInside
使用自动完成功能的方式,它看起来比我应该用于 action:
参数的字符串更整洁、更安全。所以我搜索并找到了this tutorial,它使用枚举来替换"magic strings"。
我创建了一个这样的枚举:
enum functionForAction: Selector {
case clearTapped = "clearTapped:"
case submitTapped = "submitTapped:"
case letterTapped = "letterTapped:"
}
然后我这样使用它:
button.addTarget(self, action: functionForAction.letterTapped.rawValue, forControlEvents: .TouchUpInside)
我得到了代码补全,而且我从不尝试调用拼写错误的选择器。感觉好多了。但是有可能改进吗?我真的很想输入这个:
button.addTarget(self, action: .letterTapped, forControlEvents: .TouchUpInside)
枚举可以让我在 Swift 发生这种情况吗?
有两种方法可以做到这一点,虽然可以得到您想要的语法,但我认为第二种方法很可能是更好的方法。
为了做你想做的事,我们将像你一样创建一个枚举,但也会向 UIControl
添加一个扩展(UIButton
的 superclass),这样我们可以使用 ControlSelector
添加目标
enum ControlSelector: Selector {
case ClearTapped = "clearTapped:"
case SubmitTapped = "submitTapped:"
case LetterTapped = "letterTapped:"
}
extension UIControl {
func addTarget(target: AnyObject?, action: ControlSelector, forControlEvents controlEvents: UIControlEvents) {
addTarget(target, action: action.rawValue, forControlEvents: controlEvents)
}
}
现在我们可以使用您喜欢的语法调用 addTarget
:
button.addTarget(self, action: .ClearTapped, forControlEvents: .TouchUpInside)
(顺便说一下,按照惯例,枚举的第一个字母通常是大写字母,这就是为什么我从你的代码中稍微改变了它。)
但是,这可能会变得混乱,除非您希望 ControlSelector
枚举在所有代码之间共享(现在,让选择器更清晰有什么意义)?要使此功能适用于您的所有代码,您要么必须保持两个 public 的访问级别,要么在您希望以这种方式编写内容的每个文件中写入 UIControl
扩展名。
我建议改用私有 class 来保持选择器清晰。
private class ControlSelector {
static var clearTapped: Selector = "clearTapped:"
static var submitTapped: Selector = "submitTapped:"
static var letterTapped: Selector = "letterTapped:"
}
您将不再需要协议扩展,而是这样调用您的 addTarget
方法:
button.addTarget(self, action: ControlSelector.clearTapped, forControlEvents: .TouchUpInside)
希望对您有所帮助!
我正在为我的 letterTapped()
函数向 UIButton 添加一个目标,如下所示:
button.addTarget(self, action: "letterTapped:", forControlEvents: .TouchUpInside)
我喜欢 .TouchUpInside
使用自动完成功能的方式,它看起来比我应该用于 action:
参数的字符串更整洁、更安全。所以我搜索并找到了this tutorial,它使用枚举来替换"magic strings"。
我创建了一个这样的枚举:
enum functionForAction: Selector {
case clearTapped = "clearTapped:"
case submitTapped = "submitTapped:"
case letterTapped = "letterTapped:"
}
然后我这样使用它:
button.addTarget(self, action: functionForAction.letterTapped.rawValue, forControlEvents: .TouchUpInside)
我得到了代码补全,而且我从不尝试调用拼写错误的选择器。感觉好多了。但是有可能改进吗?我真的很想输入这个:
button.addTarget(self, action: .letterTapped, forControlEvents: .TouchUpInside)
枚举可以让我在 Swift 发生这种情况吗?
有两种方法可以做到这一点,虽然可以得到您想要的语法,但我认为第二种方法很可能是更好的方法。
为了做你想做的事,我们将像你一样创建一个枚举,但也会向 UIControl
添加一个扩展(UIButton
的 superclass),这样我们可以使用 ControlSelector
enum ControlSelector: Selector {
case ClearTapped = "clearTapped:"
case SubmitTapped = "submitTapped:"
case LetterTapped = "letterTapped:"
}
extension UIControl {
func addTarget(target: AnyObject?, action: ControlSelector, forControlEvents controlEvents: UIControlEvents) {
addTarget(target, action: action.rawValue, forControlEvents: controlEvents)
}
}
现在我们可以使用您喜欢的语法调用 addTarget
:
button.addTarget(self, action: .ClearTapped, forControlEvents: .TouchUpInside)
(顺便说一下,按照惯例,枚举的第一个字母通常是大写字母,这就是为什么我从你的代码中稍微改变了它。)
但是,这可能会变得混乱,除非您希望 ControlSelector
枚举在所有代码之间共享(现在,让选择器更清晰有什么意义)?要使此功能适用于您的所有代码,您要么必须保持两个 public 的访问级别,要么在您希望以这种方式编写内容的每个文件中写入 UIControl
扩展名。
我建议改用私有 class 来保持选择器清晰。
private class ControlSelector {
static var clearTapped: Selector = "clearTapped:"
static var submitTapped: Selector = "submitTapped:"
static var letterTapped: Selector = "letterTapped:"
}
您将不再需要协议扩展,而是这样调用您的 addTarget
方法:
button.addTarget(self, action: ControlSelector.clearTapped, forControlEvents: .TouchUpInside)
希望对您有所帮助!