Class UITextField and Protocol UITextFieldDelegate

UITextField and UITextFieldDelegate let us input one line of text. UITextView (in this example) and UITextViewDelegate let us input and display many lines of text. See Text Fields in the HIG, Managing Text Fields, and key clicks.

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

The UITextField has already adopted 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 textFieldShouldReturn: and textFieldDidEndEditing: methods for the delegate. You can see these methods in View.m.

The text field font defaults to systemFontOfSize: 17 points. (One inch equals 72 points.) initWithFrame: makes the text field tall enough to hold a line in a larger font.

The keyboard is 216 pairs of pixels high (432 pixels) on a 4-inch diagonal retina iPhone in portrait orientation. This fact is nowhere in Apple’s documentation, and may thus change without warning. See Moving Content that is Located Under the Keyboard. In iOS 7, the keyboad is translucent. That’s why it’s bluish in the above screenshot.

Source code in Pig.zip

  1. main.m
  2. Class PigAppDelegate
  3. Class View

Things to try

  1. Try a different border style: UITextBorderStyleNone, UITextBorderStyleBezel, UITextBorderStyleRoundedRect.

  2. The clear button is the × in the circle. Try a different clear button mode: UITextFieldViewModeNever (the clear button is never visible), UITextFieldViewModeWhileEditing (the clear button is visible only while editing), etc.

  3. Hold down the letter N on the pop-up keyboard and watch the variants appear: ŃÑN.

  4. Try a different keyboard type: UIKeyBoardTypeDefault (the default), UIKeyboardTypePhonePad, UIKeyboardTypeEmailAddress, etc.

  5. Try a different return key type: UIReturnKeyDefault, UIReturnKeyGoogle, etc.

  6. Try a different autocapitalization type: UITextAutocapitalizationTypeNone, UITextAutocapitalizationTypeWords, UITextAutocapitalizationTypeSentences, UITextAutocapitalizationTypeAllCharacters.

  7. Try a different autocorrection type: UITextAutocorrectionTypeYes, 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 rangeOfString:.

  10. Does it matter whether textFieldShouldReturn: returns YES or NO? What difference does it make? It makes no difference to UIControlEventEditingDidEndOnExit or to UITextFieldTextDidEndEditingNotification.

  11. Create a text field that lets the user type a social security number (e.g., 123456789 with no dashes). Change the keyboard type to UIKeyboardTypeNumberPad. Use an NSRegularExpression to accept only a line that consists of exactly nine digits and no other characters.
    - (BOOL) textFieldShouldReturn: (UITextField *) tf {
    	if ([tf.text isEqualToString: @""]) {
    		textField.placeholder = @"";
    	} else {
    		NSError *error = nil;
    		NSRegularExpression *regex = [NSRegularExpression
    			regularExpressionWithPattern: @"^\\d{9}$"
    			options: 0
    			error: &error];
    
    		if (regex == nil) {
    			NSLog(@"didn't create regex: %@", error);
    		} else {
    			NSUInteger numberOfMatches = [regex
    				numberOfMatchesInString: tf.text
    				options: 0
    				range: NSMakeRange(0, [tf.text length])];
    
    			if (numberOfMatches == 1) {
    				[tf resignFirstResponder];	//Hide keyboard.
    			}
    		}
    	}
    	return YES;
    }
    

  12. Create a text field that lets the user type a social security number (e.g., 123-45-6789). Add the following method to the text field delegate. It makes the app insert the two dashes as the user enters the digits. Of course, you’d have to make it smarter if you want to allow the user to delete a character that is already in the text field.
    /*
    This method is called after the user enters (or deletes) each character.
    It inserts a dash after the third and fifth digit of the social security number.
    */
    
    - (BOOL) textField: (UITextField *) tf
    	shouldChangeCharactersInRange: (NSRange) range
    	replacementString: (NSString *) string {
    
    	//Insert (or delete) the character that the user just entered.
    	tf.text = [tf.text stringByReplacingCharactersInRange: range withString: string];
    
    	//If the text field now holds 3 or 6 characters, append a dash.
    	if (tf.text.length == 3 || tf.text.length == 6) {
    		tf.text = [tf.text stringByAppendingString: @"-"];
    	}
    
    	//The character that the user entered has already been inserted,
    	//so there's no need to insert it again.
    	return NO;
    }