在函数中作为参数供select器使用,以快捷方式传递闭包

我试图创build一个通用的button创build函数,在其中传递一个闭包,该闭包代表由于单击button而产生的操作。 我的代码如下。 但是,我得到以下错误:#select器的参数不能引用属性。 任何build议的解决方法? 除了目标操作之外,我不想编写其他所有内容相同的单独函数。

func myButton(textColor tColor:UIColor , title:String, _ buttonFcn: (UIButton) -> Void, titleSize:CGFloat=30) -> UIButton { let newButton = UIButton(type: .System) let bgColor = UIColor(red:204/255, green:204/255, blue:204/255, alpha:1.0) newButton.backgroundColor = bgColor newButton.setTitle(title, forState: .Normal) newButton.setTitleColor(tColor, forState: .Normal) newButton.titleLabel?.font = newButton.titleLabel?.font.fontWithSize(titleSize) newButton.addTarget(self, action:#selector(buttonFcn), forControlEvents: UIControlEvents.TouchUpInside) return newButton } 

问题在于目标动作机制是一个Objective-C机制,因此是基于动作select器是对象 方法的概念。 因此,您需要拥有一些基于NSObject的对象 ,该对象将此函数作为方法 ,然后可以将其作为目标。

因此,如果每种情况下的目标和动作有所不同,则需要传递的是与select器string一起对目标的引用。 Swift会在这方面发出警告,但是如果你知道如何正确地形成一个select器string,那么你肯定可以避开它。 你只是不能使用#selectorselect器语法,所以如果你错误地构造了select器string,你将面临崩溃的风险。 但是这正是我们以前在Objective-C时代所做的那种事情,所以如果这是您的目标,就请继续前进。

完全是人为的但是工作的例子:

 func buttonMaker(target:NSObject, selectorString:String) -> UIButton { let b = UIButton(type:.system) b.setTitle("Testing", for: .normal) b.addTarget(target, action: Selector(selectorString), for: .touchUpInside) b.sizeToFit() return b } 

这里是如何从视图控制器调用它:

 func doButton(_ sender:Any) { print("ha!") } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let b = buttonMaker(target:self, selectorString:"doButton:") b.frame.origin = CGPoint(x:100, y:100) self.view.addSubview(b) } 

而当我们点击button,我们不会崩溃(而是,我们打印“哈”),因为我知道如何正确地selectstring。 但是,正如你所看到的,要做到这一点,我不得不放弃使用#selector ,所以安全就在窗外。 如果我错误地写了我的select符string – 例如,如果我拼写错了,或省略了冒号 – 我们就会在button水龙头上崩溃,就像我们以前一直使用Swift #selector和Objective-C @selector被发明了。