Apple TV: don't show system keyboard

2019-08-05 10:08发布

问题:

I created a new single-view tvOS project and successfully hooked up a UITextField:

import UIKit

class ViewController: UIViewController {
    @IBAction func onChangeEditing(_ sender: UITextField) {
        NSLog("Editing changed: %@", sender.text!)
    }
}

As expected, I received log output on each key press, showing the currently entered text.

I then tried to hide the on-screen keyboard:

import UIKit

class ViewController: UIViewController {
    @IBAction func onStartEditing(_ sender: UITextField) {
        // Hide the keyboard
        if sender.responds(to: #selector(UIResponder.resignFirstResponder)) {
            sender.resignFirstResponder()
        }
    }

    @IBAction func onChangeEditing(_ sender: UITextField) {
        NSLog("Editing changed: %@", sender.text!)
    }
}

The app crashed on calling sender.resignFirstResponder():

2018-02-24 00:32:00.321224+1100 tvApp[712:296064] -[tvApp.ViewController onChangeText:]: unrecognized selector sent to instance 0x101401f90
2018-02-24 00:32:00.321396+1100 tvApp[712:296064] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[tvApp.ViewController onChangeText:]: unrecognized selector sent to instance 0x101401f90'
*** First throw call stack:
(0x18b3f94f8 0x18a67c528 0x18b4068a8 0x18b3fed98 0x18b2e439c 0x193f444c4 0x193f44444 0x193f2f840 0x194027f18 0x193fffdbc 0x194a57ba4 0x193fa9f64 0x194027c9c 0x1003a83e0 0x1003a84dc 0x193f444c4 0x193f44444 0x193f2f840 0x194a5dbd4 0x193ffff10 0x193f8f1ac 0x193f8f608 0x193ffec24 0x194a56f88 0x1945213c4 0x194525944 0x19408720c 0x193f40a7c 0x19450f2f8 0x19450ee68 0x19450e0fc 0x193f3eabc 0x193f108c0 0x1a2959a4c 0x19417c638 0x1940aa628 0x1942ab458 0x1942ab458 0x1942ab458 0x1940a9af8 0x194181408 0x1a2954d10 0x19478a5bc 0x19478d034 0x194786304 0x18b3a1c6c 0x18b3a1bec 0x18b3a1474 0x18b39f04c 0x18b2bf328 0x18d17cf84 0x193f73030 0x1003a9ca0 0x18ade79f8)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

I tried another trick:

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var textField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Replace the keyboard with a dummy view
        textField.inputView = UIView()
    }


    @IBAction func onChangeEditing(_ sender: UITextField) {
        NSLog("Editing changed: %@", sender.text!)
    }
}

This time, a new exception:

2018-02-24 00:54:40.823359+1100 tvApp[754:301388] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'NSLayoutConstraint for <UIView: 0x133027610; frame = (0 0; 1920 1080); opaque = NO; autoresize = W+H; layer = <CALayer: 0x1c403f0c0>>: A multiplier of 0 or a nil second item together with a location for the first attribute creates an illegal constraint of a location equal to a constant. Location attributes must be specified in pairs.'
*** First throw call stack:
(0x18b3f94f8 0x18a67c528 0x18b3f9440 0x18bf32b78 0x18bd5d134 0x1944a9208 0x1944a4fec 0x1944a4958 0x194a5e3f0 0x194a5da20 0x193ffff10 0x193f8f1ac 0x193f8f608 0x193ffec24 0x194a56f88 0x1945213c4 0x194525944 0x19408720c 0x193f40a7c 0x19450f2f8 0x19450ee68 0x19450e0fc 0x193f3eabc 0x193f108c0 0x1a2959a4c 0x19417c638 0x1940aa628 0x1942ab458 0x1942ab458 0x1942ab458 0x1940a9af8 0x194181408 0x1a2954d10 0x19478a5bc 0x19478d034 0x194786304 0x18b3a1c6c 0x18b3a1bec 0x18b3a1474 0x18b39f04c 0x18b2bf328 0x18d17cf84 0x193f73030 0x100ea9c94 0x18ade79f8)
libc++abi.dylib: terminating with uncaught exception of type NSException

How can I hide the system keyboard, either by not showing any keyboard at all or by completely replacing the system keyboard with my own view?