Swift의 button.addTarget 액션에 매개 변수 첨부
buttonClicked 작업에 추가 매개 변수를 전달하려고하는데 Swift에서 구문이 무엇인지 확인할 수 없습니다.
button.addTarget(self, action: "buttonClicked:", forControlEvents: UIControlEvents.TouchUpInside)
내 buttonClicked 메서드 :
func buttonClicked(sender:UIButton)
{
println("hello")
}
누구 아이디어?
당신의 도움을 주셔서 감사합니다.
에서 맞춤 매개 변수를 전달할 수 없습니다 addTarget:. 하나의 대안은 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")
}
buttonClicked 메서드에 추가 매개 변수 (예 : indexPath 또는 urlString)를 보내려면 UIButton을 하위 클래스화할 수 있습니다.
class subclassedUIButton: UIButton {
var indexPath: Int?
var urlString: String?
}
ID 검사기에서 버튼의 클래스를 subclassedUIButton으로 변경해야합니다. 당신은 사용은 buttonClicked 방법 내부의 매개 변수에 액세스 할 수 있습니다 sender.indexPath또는 sender.urlString.
참고 : 버튼이 셀 내부에있는 경우 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"] ?? "")
}
이 작업을 한 번 수행하고 프로젝트 전체에서 사용합니다 (자식 클래스에 일반적인 "객체"를 만들고 원하는 것을 버튼에 넣을 수도 있습니다!). 또는 위의 예제를 사용하여 무한한 수의 키 / 문자열 매개 변수를 버튼에 넣습니다. URL, 확인 메시지 방법 등을 포함하는 데 정말 유용합니다.
As an aside, it's important that the SO community realise this there is an entire generation of bad practice being cut'n'paste round the internet by an alarming number of programmers who don't understand/haven't been taught/missed the point of the concept of object extensions
For Swift 3.0 you can use following
button.addTarget(self, action: #selector(YourViewController.YourMethodName(_:)), for:.touchUpInside)
func YourMethodName(_ sender : UIButton) {
print(sender.tag)
}
Swift 4.2
Result:
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")
}
In the file UIButton+Events.swift I've created an extension method for UIButton that binds a UIControl.Event to a completion handler called 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)
}
}
The reason why I used a custom class for binding the event is to be able to dispose the reference later when the button is deintialised. This will prevent a possible memory leak from occurring. This wasn't possible within the UIButton its extension, because I'm not allowed to implement a property nor the deinit method.
In Swift 3 make a selector like that:
button.addTarget(self, action: #selector(ViewController.multipleParamSelector(_:secondParams:)), for: .touchUpInside)
And catch the event like that:
func multipleParamSelector(_ sender: AnyObject, secondParams: AnyObject) {
}
If you have a loop of buttons like me you can try something like this
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 4.0 code (Here we go again)
The called action should marked like this because that is the syntax for swift function for exporting functions into objective c language.
@objc func deleteAction(sender: UIButton) {
}
create some working button:
let deleteButton = UIButton(type: .roundedRect)
deleteButton.setTitle("Delete", for: [])
deleteButton.addTarget(self, action: #selector(
MyController.deleteAction(sender:)), for: .touchUpInside)
Swift 5.0 code
I use theButton.tag but if i have plenty type of option, its be very long switch case.
theButton.addTarget(self, action: #selector(theFunc), for: .touchUpInside)
theButton.frame.name = "myParameter"
.
@objc func theFunc(sender:UIButton){
print(sender.frame.name)
}
For Swift 2.X and above
button.addTarget(self,action:#selector(YourControllerName.buttonClicked(_:)),
forControlEvents:.TouchUpInside)
Swift 3.0 code
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
}
You can send value in 'userinfo' and use that as parameter in the function.
참고URL : https://stackoverflow.com/questions/24814646/attach-parameter-to-button-addtarget-action-in-swift
'programing tip' 카테고리의 다른 글
| 스팬을 사용하지 않고 HTML 목록의 글 머리 기호 색상 변경 (0) | 2020.09.13 |
|---|---|
| Java는 Currying을 지원합니까? (0) | 2020.09.13 |
| 일반 bash에서 regexp를 사용하여 부분 문자열 추출 (0) | 2020.09.13 |
| AWS Lambda 오류 :“ '/ var / task / index'모듈을 찾을 수 없습니다.” (0) | 2020.09.13 |
| 다른 cmd.exe 프롬프트 내에서 새 cmd.exe 창을 만듭니다. (0) | 2020.09.13 |