将选择器(函数名称)传递给 swift 中的函数

Pass selector (function name) to function in swift

我想将一个函数的选择器传递给另一个函数。现在我只是传递字符串并执行几个 if 语句。如果我可以将实际的函数选择器传递给函数,我就可以消除所有的 if 语句。

我当前的功能:

func getBtn(i: String, f: String) -> UIBarButtonItem
{
    let btn: UIButton = UIButton();
    btn.frame=CGRectMake(0,0,30,30)
    btn.setBackgroundImage(UIImage(named:i), forState: UIControlState.Normal)
    if f == "funcOne"{ btn.addTarget(self, action: #selector(self.funcOne), forControlEvents:.TouchUpInside) }
    else if f == "funcTwo"{ btn.addTarget(self, action: #selector(self.funcTwo), forControlEvents:.TouchUpInside) }
    else if f == "funcThree"{ btn.addTarget(self, action: #selector(self.funcThree), forControlEvents:.TouchUpInside) }
    else if f == "funcFour"{ btn.addTarget(self, action: #selector(self.funcFour), forControlEvents:.TouchUpInside) }
    // etc.
    let barBtn = UIBarButtonItem(customView: btn)
    return barBtn;
}

用法:

items.append(self.getBtn("checkmark",f:"funcOne"));

我希望能够做的事情:

func getBtn(i: String, f: SOME_TYPE_OF_THING) -> UIBarButtonItem
{
    let btn: UIButton = UIButton();
    btn.frame=CGRectMake(0,0,30,30)
    btn.setBackgroundImage(UIImage(named:i), forState: UIControlState.Normal)
    btn.addTarget(self, action: #selector(f), forControlEvents:.TouchUpInside)
    let barBtn = UIBarButtonItem(customView: btn)
    return barBtn;
}

用法:

items.append(self.getBtn("checkmark",f:self.funcOne));

#selector() 语法的目的是避免将选择器写成文字字符串时可能出现的错误,这种情况很容易出错。不过,您可以自由编写 Selector(f) 而不是使用 #selector() 语法。

但是,如果 f 本身被键入为选择器,那就更好了:

func getBtn(i: String, f: Selector) -> UIBarButtonItem

这样,您可以继续使用 #selector,但在通话中使用:

items.append(self.getBtn("checkmark",f:#selector(funcOne)))

getBtn 中,您只需将 f 作为按钮操作直接传递即可。

您还可以在 swift 中将函数作为参数传递——参数本质上是方法签名。这是一个简单的例子,它将 运行 在 Playground 中:

func myFunc(s:String) -> String
{
    return ("Hello \(s)")
}

func myOtherFunc(s:String) -> String
{
    return ("Goodbye \(s)")
}

func someOtherFunc(aFunction:String -> String) -> String
{
    return aFunction("test")
}

print(someOtherFunc(myFunc))
print(someOtherFunc(myOtherFunc))

我不确定这是否是您想要的,但有时它很有用。然后你可以这样做:

items.append(self.getBtn("checkmark",f:funcOne))

然后更改 self.getBtn 方法以期待该功能。像这样:

func funcOne()
{
    print("Executing func one")
}

func getBtn(i: String, f: () -> ()) -> UIBarButtonItem
{
    let btn: UIButton = UIButton();
    btn.frame=CGRectMake(0,0,30,30)
    btn.setBackgroundImage(UIImage(named:i), forState: UIControlState.Normal)
    btn.addTarget(self, action: f, forControlEvents:.TouchUpInside)
    let barBtn = UIBarButtonItem(customView: btn)
    return barBtn;
}