2016-08-19 12 views
2

関数のセレクタを別の関数に渡したいと思います。今私は文字列を渡していくつかの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)); 

答えて

3

#selector()構文の目的は、エラーが発生しやすいリテラル文字列としてセレクタを記述しなければならないというエラーからあなたを救うことです。それにもかかわらず、#selector()の構文を使用する代わりに、Selector(f)と書くことは自由です。

fがセレクタとしての地位を入力した場合しかし、それも良いだろう:あなたは#selectorを使用し続けるが、コールでそれを行うことができ

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

その方法:getBtn

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

fを直接ボタンアクションとして渡すだけです。

+0

ありがとうございます。私は間違いがない。まさに私が望んでいたもの。今ビルドでテストされます。 –

+0

完璧に動作します。ありがとう。 2分で受け入れます。 –

+0

喜んで助けてください。これを単にアクションの初期段階に '#selector 'の使用を"後退させる "方法と考えてください。呼び出し先で実行するのではなく、呼び出し元で実行します。 – matt

0

また、関数をパラメータとしてパラメータに渡すこともできます。パラメータは基本的にメソッドのシグネチャです。ここではプレイグラウンドで実行されます簡単な例です:

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; 
} 
+0

Swiftでは関数をパラメータとして渡すことができますが、Objective-Cセレクタが期待される場所(つまり 'action:'引数)に関数を渡すことはできません。 – matt

+1

特にコンパイルされていない場合は、テストされていないコードを表示することは残念です。 – matt

関連する問題