传递选择器(函数名称)以在swift中运行

时间:2016-08-19 16:41:51

标签: swift func

我想将函数的选择器传递给另一个函数。现在我只是传递字符串并执行几个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));

2 个答案:

答案 0 :(得分:10)

#selector()语法的目的是为了避免因必须将选择器编写为文字字符串而导致错误,这很容易出错。不过,您可以自由编写Selector(f)而不是使用#selector()语法。

但是,如果f本身被键入为Selector:

,那就更好了
func getBtn(i: String, f: Selector) -> UIBarButtonItem

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

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

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

答案 1 :(得分:-1)

你也可以在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;
}