ButtonClickedアクションに追加のパラメーターを渡そうとしていますが、Swiftの構文がどうあるべきかを判断できません。
button.addTarget(self, action: "buttonClicked:", forControlEvents: UIControlEvents.TouchUpInside)
私のbuttonClickedメソッド:
func buttonClicked(sender:UIButton)
{
println("hello")
}
誰でもアイデアはありますか?
ご協力いただきありがとうございます。
addTarget:
でカスタムパラメータを渡すことはできません。1つの代替方法は、ボタンのtag
プロパティを設定し、タグに基づいて動作することです。
button.tag = 5
button.addTarget(self, action: "buttonClicked:",
forControlEvents: UIControlEvents.TouchUpInside)
またはSwift 2.2以上の場合:
button.tag = 5
button.addTarget(self,action:#selector(buttonClicked),
forControlEvents:.TouchUpInside)
tag
プロパティに基づいてロジックを実行するようになりました
@objc func buttonClicked(sender:UIButton)
{
if(sender.tag == 5){
var abc = "argOne" //Do something for tag 5
}
print("hello")
}
IndexClickやurlStringなどの追加のパラメーターをbuttonClickedメソッドに送信する場合、UIButtonをサブクラス化できます。
class subclassedUIButton: UIButton {
var indexPath: Int?
var urlString: String?
}
IDインスペクターのボタンのクラスを必ずsubclassedUIButtonに変更してください。 sender.indexPath
またはsender.urlString
を使用して、buttonClickedメソッド内のパラメーターにアクセスできます。
注:ボタンがセル内にある場合は、cellForRowAtIndexPathメソッド(ボタンが作成される場所)でこれらの追加パラメーターの値を設定できます。
皆さんがタグを使用していると言ってくれて感謝していますが、実際にはUIButtonクラスを拡張し、そこにオブジェクトを追加する必要があります。
タグはこれに絶望的な方法です。このようにUIButtonを拡張します(Swift 4)
import UIKit
class PassableUIButton: UIButton{
var params: Dictionary<String, Any>
override init(frame: CGRect) {
self.params = [:]
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
self.params = [:]
super.init(coder: aDecoder)
}
}
あなたの呼び出しは呼び出しかもしれません(Selector(("webButtonTouched:"))
のコロン「:」に注意してください)
let webButton = PassableUIButton(frame: CGRect(x:310, y:40, width:40, height:40))
webButton.setTitle("Visit",for: .normal)
webButton.addTarget(self, action: #selector(YourViewController.webButtonTouched(_:)), for:.touchUpInside)
webButton.params["myvalue"] = "bob"
そして最後にここですべてをキャッチします
@IBAction func webButtonTouched(_ sender: PassableUIButton) {
print(sender.params["myvalue"] ?? "")
}
これを1回行い、プロジェクト全体で使用します(子クラスに汎用の「オブジェクト」を持たせ、ボタンに好きなものを入れることさえできます!)。または、上記の例を使用して、無制限の数のキー/文字列パラメータをボタンに挿入します。URL、確認メッセージの方法論などを含めるのに非常に便利です。
余談ですが、SO
コミュニティが、理解できないプログラマーの驚くべき数によってインターネット全体にカットアンドペーストされている悪い習慣の全世代がこれを認識していることは重要ですobject extensions
の概念のポイントを教えていない/見逃していない
Swift 3.0の場合、次を使用できます
button.addTarget(self, action: #selector(YourViewController.YourMethodName(_:)), for:.touchUpInside)
func YourMethodName(_ sender : UIButton) {
print(sender.tag)
}
Swift 4.2
結果:
testButton.on(.touchUpInside) { (sender, event) in
// You can use any reference initialized before the code block here
// You can access self by adding [weak self] before (sender, event)
// You can then either make self strong by using a guard statement or use a optional operator (?)
print("user did press test button")
}
ファイルUIButton+Events.Swift
で、UIButton
という拡張メソッドを作成し、UIControl.Event
をEventHandler
という完了ハンドラーにバインドします。
import UIKit
fileprivate var bindedEvents: [UIButton:EventBinder] = [:]
fileprivate class EventBinder {
let event: UIControl.Event
let button: UIButton
let handler: UIButton.EventHandler
let selector: Selector
required init(
_ event: UIControl.Event,
on button: UIButton,
withHandler handler: @escaping UIButton.EventHandler
) {
self.event = event
self.button = button
self.handler = handler
self.selector = #selector(performEvent(on:ofType:))
button.addTarget(self, action: self.selector, for: event)
}
deinit {
button.removeTarget(self, action: selector, for: event)
if let index = bindedEvents.index(forKey: button) {
bindedEvents.remove(at: index)
}
}
}
private extension EventBinder {
@objc func performEvent(on sender: UIButton, ofType event: UIControl.Event) {
handler(sender, event)
}
}
extension UIButton {
typealias EventHandler = (UIButton, UIControl.Event) -> Void
func on(_ event: UIControl.Event, handler: @escaping EventHandler) {
bindedEvents[self] = EventBinder(event, on: self, withHandler: handler)
}
}
イベントをバインドするためにカスタムクラスを使用した理由は、後でボタンが初期化されたときに参照を破棄できるようにするためです。これにより、メモリリークの発生を防ぐことができます。プロパティを実装することもUIButton
メソッドを実装することも許可されていないため、deinit
の拡張内ではこれは不可能でした。
Swift 3で、そのようなセレクターを作成します。
button.addTarget(self, action: #selector(ViewController.multipleParamSelector(_:secondParams:)), for: .touchUpInside)
そして、そのようなイベントをキャッチします。
func multipleParamSelector(_ sender: AnyObject, secondParams: AnyObject) {
}
Swift 4.0コード(ここでまた行きます)
呼び出されたアクションは、Objective C言語に関数をエクスポートするためのSwift関数の構文であるため、このようにマークする必要があります。
@objc func deleteAction(sender: UIButton) {
}
作業ボタンを作成します。
let deleteButton = UIButton(type: .roundedRect)
deleteButton.setTitle("Delete", for: [])
deleteButton.addTarget(self, action: #selector(
MyController.deleteAction(sender:)), for: .touchUpInside)
私のようなボタンのループがある場合は、このようなものを試すことができます
var buttonTags:[Int:String]? // can be [Int:Any]
let myArray = [0:"a",1:"b"]
for (index,value) in myArray {
let button = // Create a button
buttonTags?[index] = myArray[index]
button.tag = index
button.addTarget(self, action: #selector(buttonAction(_:)), for: .touchDown)
}
@objc func buttonAction(_ sender:UIButton) {
let myString = buttonTags[sender.tag]
}
Swift 5.0コード
私はtheButton.tagを使用しますが、オプションの種類が豊富な場合、非常に長いスイッチケースになります。
theButton.addTarget(self, action: #selector(theFunc), for: .touchUpInside)
theButton.frame.name = "myParameter"
。
@objc func theFunc(sender:UIButton){
print(sender.frame.name)
}
Swift 2.X以降の場合
button.addTarget(self,action:#selector(YourControllerName.buttonClicked(_:)),
forControlEvents:.TouchUpInside)
Swift 3.0コード
self.timer = Timer.scheduledTimer(timeInterval: timeInterval, target: self, selector:#selector(fetchAutocompletePlaces(timer:)), userInfo:[textView.text], repeats: true)
func fetchAutocompletePlaces(timer : Timer) {
let keyword = timer.userInfo
}
「userinfo」で値を送信し、それを関数のパラメーターとして使用できます。