Text Fields:
class UITextField and protocol UITextFieldDelegate

Tap the yellow UITextField, type a word, and press Done to translate your word into Pig Latin. What happens if you press Done when nothing is typed?

The UITextField and UITextFieldDelegate in this app let us input one line of text. The UITextView (in the text view app) and UITextViewDelegate let us input and display many lines of text. See Text Fields in the iOS Human Interface Guidelines, Managing Text Fields, and key clicks.

Our View contains a UITextField, which is a control object that has one delegate object. The ViewController acts as the UITextField’s delegate. In addition to the delegate, a text field may have zero or more targets. For simplicity, our text field has no targets.

The UITextField already conforms to the UITextInput protocol, which inherits from the UIKeyInput protocol, which inherits from the UITextInputTraits protocol, which includes properties such as keyboardType and autoCapitalizationType. We will have to make the delegate adopt the UITextFieldDelegate protocol. That means we have to write the name of the protocol at the end of the class line at the top of the file ViewController.swift, and we have to give the delegate the methods textFieldShouldReturn(_:) and textFieldDidEndEditing(_:). See also the AVAudioPlayerDelegate protocol in Switch.

The text field font defaults to the systemFont(ofSize:) 17 points. (One inch equals 72 points.) The View makes the text field and label tall enough to hold a line of text in the larger font we selected. The iOS 11 keyboad is slightly translucent.

The Bool return value of textFieldShouldReturn(_:)

The usual way to dismiss the UITextField’s keyboard is to have textFieldShouldReturn(_:) call resignFirstResponder(). Another way to dismiss the keyboard is to let the UITextField be the target object of an action method for the control event UIControlEvents.editingDidEndOnExit. In this case, the action method and textFieldShouldReturn(_:) should not call resignFirstResponder(). If textFieldShouldReturn(_:) returns true, the keyboard will be dismissed and the action method will be called.

Source code in TextField.zip

In the iOS Simulator,
Hardware → Keyboard → uncheck Connect Hardware Keyboard

  1. Class AppDelegate: unchanged.
  2. Class ViewController conforms to protocol UITextFieldDelegate. I added the methods textFieldShouldReturn(_:) and textFieldDidEndEditing(_:).
  3. Class View contains two subviews, the UITextField and UILabel.
  4. Info.plist: unchanged.

Things to try

  1. Try a different border style:
    1. UITextBorderStyle.none
    2. UITextBorderStyle.bezel (also set textField.layer.borderWidth = 4.0;)
    3. UITextBorderStyle.roundedRect

  2. The clear button is the × in the circle. Try a different clear button mode:
    1. UITextFieldViewMode.never (the clear button is never visible)
    2. UITextFieldViewMode.whileEditing (the clear button is visible only while editing)
    3. etc.

  3. Hold down the letter N on the pop-up keyboard and watch the variants appear: ń ñ n.

  4. Try a different keyboard type:
    1. UIKeyBoardType.default (the default)
    2. UIKeyBoardType.phonePad
    3. UIKeyBoardType.emailAddress
    4. etc.

  5. Try a different return key type:
    1. UIReturnKeyType.default
    2. UIReturnKeyType.google (it says SEARCH, not GOOGLE)
    3. etc.

  6. Try a different autocapitalization type:
    1. UITextAutocapitalizationType.none
    2. UITextAutocapitalizationType.words
    3. UITextAutocapitalizationType.sentences
    4. UITextAutocapitalizationType.allCharacters

  7. Try a different autocorrection type: UITextAutocorrectionType.yes, etc.

  8. Turn on secure text entry.

  9. Instead of rejecting the null string, have it reject the string "watermelon". Even better, reject any string that contains "watermelon". See contains.

  10. Create a text field that lets the user type a social security number (e.g., 123456789 with no dashes). The UIKeyboardType.numberPad keyboard has no Done button, so if you change to this keyboard type, you will have to create a separate button. Use an NSRegularExpression to accept only a line that consists of exactly nine digits and no other characters.
    	//Called when return key is pressed.
    	//If input consists of exactly 9 digits, accept it and hide the keyboard.
    	func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    		let regex: NSRegularExpression;
    		do {
    			try regex = NSRegularExpression(pattern: "^\\d{9}$", options: NSRegularExpression.Options());
    		} catch {
    			print("bad regex \(error)");
    			textField.resignFirstResponder();	//Hide keyboard.
    			return false;
    		let numberOfMatches: Int = regex.numberOfMatches(in: textField.text!,
    			range: NSRange(textField.text!.startIndex..., in: textField.text!));
    		if numberOfMatches == 1 {
    			textField.resignFirstResponder();	//Hide keyboard.
    			return true;
    		return false;

  11. How much real estate does the keyboard cover when it slides up? Discover its dimensions in points. Append the following statements to the end of the init(coder:) method of class View. See Notify and Moving Content that is Located Under the Keyboard.
    		//Ask the notification center to call the method keyboardDidShow
    		//when the keyboard apears.
    		let center: NSNotificationCenter = NSNotificationCenter.defaultCenter();
    			selector: #selector(keyboardDidShow(_:)),
    			name: UIKeyboardDidShowNotification,
    			object: nil);
    Add the following method to class View.
    	//Call this method when the keyboard appears.
    	//An NSValue is an object that can contain a structure, in this case a CGRect structure.
    	func keyboardDidShow(notification: NSNotification) {
    		let userInfo: [NSObject: AnyObject]? = notification.userInfo;	//an optional dictionary
    		if userInfo != nil {
    			let value: NSValue = userInfo![UIKeyboardFrameBeginUserInfoKey] as! NSValue;
    			let rect: CGRect = value.CGRectValue();

    On iPhone 6s Plus in portrait orientation, the size of the keyboard was the following (in points).

    (414.0, 226.0)
    In landscape, it was 736 × 162 points.