3

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?

Xcoder
  • 1,433
  • 3
  • 17
  • 37

2 Answers2

2

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")
    }

}

neoneye
  • 50,398
  • 25
  • 166
  • 151
  • 2
    It seems, that this solution no longer works. Tried on iOS 15.5 with external bluetooth keyboard. Other `UIKeyCommand` input strings works fine (e.g. inputEscape, ...), but not the Up/Down/Left/Right keys. – SchmidtFx Jul 11 '22 at 11:45
2

I found this to work on iOS/iPadOS using a view controller. The key is leveraging wantsPriorityOverSystemBehavior:

override var keyCommands: [UIKeyCommand]? {
    let upArrow = UIKeyCommand(input: UIKeyCommand.inputUpArrow, modifierFlags: [], action: #selector(test))
    upArrow.wantsPriorityOverSystemBehavior = true

    return [upArrow]
}

@objc func test(_ sender: UIKeyCommand) {
    print(">>> test was pressed")
}