0

I want to add dynamic number of buttons to my VC. So i am looping through my buttons array model and instantiating UIButtons. The problem is with adding target to these buttons. I want to pass in a string to the selector when adding a target, however Xcode compiler doesn't let me do that

Argument of '#selector' does not refer to an '@objc' method, property, or initializer

@objc func didTapOnButton(url: String) { }
let button = UIButton()
button.addTarget(self, action: #selector(didTapOnButton(url: "Random string which is different for every bbutton ")), for: .touchUpInside)

Is there any other solution other than using a custom UIButton

PK-V
  • 194
  • 1
  • 9
  • 1
    Does this answer your question? [Passing arguments to selector in Swift](https://stackoverflow.com/questions/43251708/passing-arguments-to-selector-in-swift) – timbre timbre Oct 13 '21 at 20:02
  • I think you misunderstand how selectors work. You are not passing the argument with some value, you are passing signature of the function, which can include selector. See the link I posted, it's explained well in the top answer there. – timbre timbre Oct 13 '21 at 20:03

1 Answers1

0

I don't think it is possible to do what you are attempting, you can try like this:

var buttons: [UIButton: String] = []

let button = UIButton()
let urlString = "Random string which is different for every button"
buttons[button] = urlString
button.addTarget(self, action: #selector(didTapOnButton), for: .touchUpInside

@objc func didTapOnButton(sender: UIButton) { 
    let urlString = self.buttons[sender]
    // Do something with my URL
}

As I remember UIButton is hashable...

Another option would be to extend UIButton to hold the information you want:

extension UIButton {
     private static var _urlStringComputedProperty = [String: String]()
     var urlString String {
        get {
            let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
            return Self._urlStringComputedProperty[tmpAddress]
        }
        set(newValue) {
            let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
            Self._urlStringComputedProperty[tmpAddress] = newValue
        }
     }
}

let button = UIButton()
button.urlString = "Random string which is different for every button"
button.addTarget(self, action: #selector(didTapOnButton), for: .touchUpInside

@objc func didTapOnButton(sender: UIButton) { 
    let urlString = sender.urlString
    // Do something with my URL
}