Search code examples
swiftuigesturerecognizerunrecognized-selector

Swift: addGestureRecognizer not work in class


My class:

class SelectBox {
    internal static func openSelector(list:[String: String], parent:UIView){
        print("iosLog HELLO")
        parent.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleClick(sender:))))
    }

    @objc func handleClick(sender: UITapGestureRecognizer) {
        print("iosLog CLICK")
    }
}

Set view :

SelectBox.openSelector(list: AppDelegate.stateList, parent: bgPlaceInto)

After launch print HELLO, but after click on view i get below error :

2018-07-07 18:39:12.298322+0430 Ma[971:260558] [ChatService]: SMT: 2018-07-07 18:39:12.470392+0430 Ma[971:260525] [ChatService]: RCV: 2018-07-07 18:39:12.471851+0430 Ma[971:260591] [ChatService]: RCV: 2018-07-07 18:39:14.674675+0430 Ma[971:260392] *** NSForwarding: warning: object 0x100a9fc70 of class 'Ma.SelectBox' does not implement methodSignatureForSelector: -- trouble ahead Unrecognized selector +[Ma.SelectBox handleClickWithSender:] 2018-07-07 18:39:14.675210+0430 Ma[971:260392] Unrecognized selector +[Ma.SelectBox handleClickWithSender:]

How i can set click listener to view by class?

Thank you


Solution

  • Your openSelector method is static. The word self in a static context, refers to an instance of the surrounding type's meta type. In this case, SelectorBox.Type.

    Obviously, SelectorBox.Type does not have a handleClick method. SelectorBox does.

    You need to make the openSelector method non-static:

    internal func openSelector(list:[String: String], parent:UIView){
        print("iosLog HELLO")
        parent.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleClick(sender:))))
    }
    

    Now self refers to the SelectorBox instance.

    You can call it like this:

    // declare this at class level:
    let box = SelectorBox()
    
    // call the method like this
    box.openSelector()
    

    EDIT: Your class should look like this:

    class ViewControllerPage: UIViewController, UITableViewDelegate, UITableViewDataSource { 
        @IBOutlet var bgGenderInto: UIView!
        let box = SelectBox()  
        override func viewDidLoad() { 
            super.viewDidLoad() 
            box.openSelector(list: AppDelegate.genderList, parent: bgGenderInto) 
        }
    }