Michael Rogers
Michael Rogers

Reputation: 1349

UIInputViewController (Custom Keyboard) - UIButton action not being triggered - Why, Oh Why?

I'm sure this is ridiculously easy, but I cannot get a simple example, with a UIInputViewController, to work. I've got two buttons, they show up, but tapping on them has no effect. In Googling, I found several questions exactly like this -- with no answers! I watched the WWDC 2017 video on the subject, but they sort of glossed over this one point, and their code works, but I couldn't see why mine doesn't.

The code (just proof of concept) is below, and any help would be hugely appreciated.

Michael

class ViewController: UIViewController {  

    @IBOutlet weak var testTF: UITextField!  

    override func viewDidLoad() {  
        super.viewDidLoad()     
        testTF.inputView = CustomView(nibName:nil,bundle:nil).inputView  
    }  

    override func didReceiveMemoryWarning() {  
        super.didReceiveMemoryWarning()  
    }  


}  
class MyButton:UIButton {  

     init(frame: CGRect, title:String) {  
        super.init(frame: frame)  
        backgroundColor = UIColor.lightGray  
        isUserInteractionEnabled = true  
        setTitle(title, for: .normal)  
    }  

    required init?(coder aDecoder: NSCoder) {  
        fatalError("init(coder:) has not been implemented")  
    }  


}  
class CustomView: UIInputViewController {  

    override init(nibName:String?, bundle:Bundle?) {  
        super.init(nibName:nibName, bundle:bundle)  
        let keyboard:UIView = UIView(frame: CGRect(x:0.0,y:0.0,width:768.0, height:240.0))  
        keyboard.backgroundColor = UIColor.red  

        let zeroKey:MyButton = MyButton(frame: CGRect(x:0.0,y:0.0,width:45.0,height:50.0), title:"0")  
        zeroKey.addTarget(self, action: #selector(clickMe(sender:)), for: .allEvents)  
        keyboard.addSubview(zeroKey)  

        let oneKey:UIButton = MyButton(frame: CGRect(x:50.0,y:0.0,width:45.0,height:50.0), title:"1")  
        oneKey.addTarget(self, action: #selector(clickMe(sender:)), for: .allEvents)  
        keyboard.addSubview(oneKey)  

        self.inputView?.backgroundColor = UIColor.blue  
        self.inputView?.frame = CGRect(x:0.0,y:0.0,width:UIScreen.main.bounds.width, height:240.0)  
        self.inputView?.isUserInteractionEnabled = true  
        self.inputView?.addSubview(keyboard)  
    }  

    required init?(coder aDecoder: NSCoder) {  
        fatalError("init(coder:) has not been implemented")  
    }  

    @objc func clickMe(sender:Any) {  
        print("hey, why am I not being called?")  
    }
}  

Upvotes: 1

Views: 2537

Answers (2)

Wil Macaulay
Wil Macaulay

Reputation: 517

A keyboard extension will be executing in a separate process from the main process. Unless you explicitly set your debugging context to the extension, only the logging that you do in your host program will appear in the Xcode log window. Although you don't say so in the above, I suspect you started out trying to debug the host program and then changed the scheme to your keyboard, which resulted in it 'just working'

See the apple docs at https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/ExtensionCreation.html#//apple_ref/doc/uid/TP40014214-CH5-SW8 for how to set up for a debugging session for extensions in Xcode.

Upvotes: 0

Aadil Ali
Aadil Ali

Reputation: 371

Remove CustomView Classs. I just did this worked fine at my side:

    override func viewDidLoad() {
    super.viewDidLoad()
    let keyboard:UIView = UIView(frame: CGRect(x:0.0,y:0.0,width:768.0, height:240.0))
    keyboard.backgroundColor = UIColor.red

    let zeroKey:MyButton = MyButton(frame: CGRect(x:0.0,y:0.0,width:45.0,height:50.0), title:"0")
    zeroKey.addTarget(self, action: #selector(clickMe(sender:)), for: .allEvents)
    keyboard.addSubview(zeroKey)

    let oneKey:UIButton = MyButton(frame: CGRect(x:50.0,y:0.0,width:45.0,height:50.0), title:"1")
    oneKey.addTarget(self, action: #selector(clickMe(sender:)), for: .touchUpInside)
    keyboard.addSubview(oneKey) 
    testTF.inputView = keyboard
}
@objc func clickMe(sender:Any) {
    print("hey, why am I not being called?")
}

enter image description here

Upvotes: 2

Related Questions