Search code examples
iosswiftuiviewkeyboardsubclass

How to detect arrow keys when subclassing a UIView?


Basically, I want to do something when one of the arrow keys are pressed.

I've read many different questions. Many of them talk about keyDown, but that is for NSViewController or NSWindow(this and this(Apple Documention)). I thought I was onto something when I used this:

func setKeys() {
    let up = UIKeyCommand(input: UIKeyCommand.inputUpArrow, modifierFlags: [], action: #selector(upPressed))
}

@objc func upPressed() {
    print("Hello")
}

However, the upPressed() isn't even called. What is the best way to accomplish this?


Solution

  • You are not using the returned UIKeyCommand instance up.

    Apple: "After creating a key command object, you can add it to a view controller using the addKeyCommand: method of the view controller. You can also override any responder class and return the key command directly from the responder’s keyCommands property."

    class Test: UIViewController{
    
       override func viewDidLoad() {
           super.viewDidLoad()
           setKeys()
       }
    
       func setKeys() {
          let up = UIKeyCommand(input: UIKeyCommand.inputUpArrow, modifierFlags: [], action: #selector(upPressed))
          self.addKeyCommand(up)
       }
    
       @objc func upPressed() {
          print("Hello")
       }
    }
    
    
    
    

    Tested this using a simulator and hardware keyboard.

    ADDITIONALLY: If you are going to implement it through the UIView directly you have to do : "...You can also override any responder class and return the key command directly from the responder’s keyCommands property." since UIView conforms to UIResponder

    class CustomView: UIView{
        override var keyCommands: [UIKeyCommand]? {
           return  [UIKeyCommand(input: UIKeyCommand.inputUpArrow, modifierFlags: [], action: #selector(upPressed))]
        }
    
        @objc func upPressed(){
            print("hello world")
        }
    
    }