iPhone OS Reference Library Apple Developer Connection spyglass button

Text and Web

The text system in iPhone OS was designed with the modest needs of mobile users in mind. The text system was designed to handle the single and multi-line text input that are commonly used in email and SMS programs. The text system also supports Unicode and has several different input methods, making it easy to display and read text in many different languages.

About Text and Web Support

The text system in iPhone OS provides a tremendous amount of power while still being very simple to use. The UIKit framework includes several high-level classes for managing the display and input of text. This framework also includes a more advanced class for displaying HTML and JavaScript-based content.

The following sections describe the basic support for text and web content in iPhone OS. For more information about each of the classes listed in this section, see UIKit Framework Reference.

Text Views

The UIKit framework provides three primary classes for displaying text content:

These classes support the display of arbitrarily large amounts of text, although labels and text fields are typically used for relatively small amounts of text. To make the displayed text easier to read on the smaller screens of iPhone OS–based devices, however, these classes do not support the kinds of advanced formatting you might find in desktop operating systems like Mac OS X. All three classes still allow you to specify the font information, including size and styling options, that you might otherwise want, but the font information you specify is applied to all of the text associated with the object.

Figure 5-1 shows examples of the available text classes as they appear on screen. These examples were taken from the UICatalog sample application, which demonstrates many of the views and controls available in UIKit. The image on the left shows several different styles of text fields while the image on the right shows a single text view. The callouts displayed on the gray background are themselves UILabel objects embedded inside the table cells used to display the different views. There is also a UILabel object with the text “Left View” at the bottom of the screen on the left.

Figure 5-1  Text classes in the UICatalog application

Text classes in the UICatalog application

When working with editable text views, you should always provide a delegate object to manage the editing session. Text views send several different notifications to the delegate to let them know when editing begins, when it ends, and to give them a chance to override some editing actions. For example, the delegate can decide if the current text contains a valid value and prevent the editing session from ending if it does not. When editing does finally end, you also use the delegate to get the resulting text value and update your application’s data model.

Because there are slight differences in their intended usage, the delegate methods for each text view are slightly different. A delegate that supports the UITextField class implements the methods of the UITextFieldDelegate protocol. Similarly, a delegate that supports the UITextView class implements the methods of the UITextViewDelegate protocol. In both cases, you are not required to implement any of the protocol methods but if you do not, the text field is not going to be of much use to you. For more information on the methods in these two protocols, see UITextFieldDelegate Protocol Reference and UITextViewDelegate Protocol Reference.

Web View

The UIWebView class lets you integrate what is essentially a miniature web browser into your application’s user interface. The UIWebView class makes full use of the same web technologies used to implement Safari in iPhone OS, including full support for HTML, CSS, and JavaScript content. The class also supports many of the built-in gestures that users are familiar with in Safari. For example, you can double-click and pinch to zoom in and out of the page and you can scroll around the page by dragging your finger.

In addition to displaying content, you can also use a web view object to gather input from the user through the use of web forms. Like the other text classes in UIKit, if you have an editable text field on a form in your web page, tapping that field brings up a keyboard so that the user can enter text. Because it is an integral part of the web experience, the web view itself manages the displaying and dismissing of the keyboard for you.

Figure 5-2 shows an example of a UIWebView object from the the UICatalog sample application, which demonstrates many of the views and controls available in UIKit. Because it just displays HTML content, if you want the user to be able to navigate pages much like they would in a web browser, you need to add controls to do so. For example, the web view in the figure occupies the space below the text field containing the target URL and does not contain the text field itself.

Figure 5-2  A web view

A web view

A web view provides information about when pages are loaded, and whether there were any load errors, through its associated delegate object. A web delegate is an object that implements one or more methods of the UIWebViewDelegate protocol. Your implementations of the delegate methods can respond to failures or perform other tasks related to the loading of a web page. For more information about the methods of the UIWebViewDelegate protocol, see UIWebViewDelegate Protocol Reference.

Keyboards and Input Methods

Whenever the user taps in an object capable of accepting text input, the object asks the system to display an appropriate keyboard. Depending on the needs of your program and the user’s preferred language, the system might display one of several different keyboards. Although your application cannot control the user’s preferred language (and thus the keyboard’s input method), it can control attributes of the keyboard that indicate its intended use, such as the configuration of any special keys and its behaviors.

You configure the attributes of the keyboard directly through the text objects of your application. The UITextField and UITextView classes both conform to the UITextInputTraits protocol, which defines the properties for configuring the keyboard. Setting these properties programmatically or in the Interface Builder inspector window causes the system to display the keyboard of the designated type.

Note: Although the UIWebView class does not support the UITextInputTraits protocol directly, you can configure some keyboard attributes for text input elements. In particular, you can include autocorrect and autocapitalization attributes in the definition of an input element to specify the keyboard’s behaviors, as shown in the following example.

<input type="text" size="30" autocorrect="off" autocapitalization="on">
You cannot specify the keyboard type in input elements. The web view displays a custom keyboard that is based on the default keyboard but includes some additional controls for navigating between form elements.

The default keyboard configuration is designed for general text input. Figure 5-3 displays the default keyboard along with several other keyboard configurations. The default keyboard displays an alphabetical keyboard initially but the user can toggle it and display numbers and punctuation as well. Most of the other keyboards offer similar features as the default keyboard but provide additional buttons that are specially suited to particular tasks. However, the phone and numerical keyboards offer a dramatically different layout that is tailored towards numerical input.

Figure 5-3  Several different keyboard types

Several different keyboard types

To facilitate the language preferences of different users, iPhone OS also supports different input methods and keyboard layouts for different languages, some of which are shown in Figure 5-4. The input method and layout for the keyboard is determined by the user’s language preferences.

Figure 5-4  Several different keyboards and input methods

Several different keyboards and input methods

Managing the Keyboard

Although many UIKit objects display the keyboard automatically in response to user interactions, your application still has some responsibilities for configuring and managing the keyboard. The following sections describe those responsibilities.

Receiving Keyboard Notifications

When the keyboard is shown or hidden, iPhone OS sends out the following notifications to any registered observers:

The system sends keyboard notifications when the keyboard first appears, when it disappears, any time the owner of the keyboard changes, or any time your application’s orientation changes. In each situation, the system sends only the appropriate subset of messages. For example, if the owner of the keyboard changes, the system sends a UIKeyboardWillHideNotification message, but not a UIKeyboardDidHideNotification message, to the current owner because the change never causes the keyboard to be hidden. The delivery of the UIKeyboardWillHideNotification is simply a way to alert the current owner that it is about to lose the keyboard focus. Changing the orientation of the keyboard does send both will and did hide notifications, however, because the keyboards for each orientation are different and thus the original must be hidden before the new one is displayed.

Each keyboard notification includes information about the size and position of the keyboard on the screen. You should always use the information in these notifications as opposed to assuming the keyboard is a particular size or in a particular location. The size of the keyboard is not guaranteed to be the same from one input method to another and may also change between different releases of iPhone OS. In addition, even for a single language and system release, the keyboard dimensions can vary depending on the orientation of your application. For example, Figure 5-5 shows the relative sizes of the URL keyboard in both the portrait and landscape modes. Using the information inside the keyboard notifications ensures that you always have the correct size and position information.

Figure 5-5  Relative keyboard sizes in portrait and landscape modes

Relative keyboard sizes in portrait and landscape modes
Note: The rectangle contained in the UIKeyboardBoundsUserInfoKey of the info dictionary should be used only for the size information it contains. Do not use the origin of the rectangle (which is always {0.0, 0.0}) in rectangle-intersection operations. Because the keyboard is animated into position, the actual bounding rectangle of the keyboard changes over time. The starting and ending positions of the keyboard are therefore stored in the info dictionary under the UIKeyboardCenterBeginUserInfoKey and UIKeyboardCenterEndUserInfoKey keys, and from these values you can compute the origin.

One reason to use keyboard notifications is so that you can reposition content that is obscured by the keyboard when it is visible. For information on how to handle this scenario, see “Moving Content That Is Located Under the Keyboard.”

Displaying the Keyboard

When the user taps a view, the system automatically designates that view as the first responder. When this happens to a view that contains editable text, the view initiates an editing session for that text. At the beginning of that editing session, the view asks the system to display the keyboard, if it is not already visible. If the keyboard is already visible, the change in first responder causes text input from the keyboard to be redirected to the newly tapped view.

Because the keyboard is displayed automatically when a view becomes the first responder, you often do not need to do anything to display it. However, you can programmatically display the keyboard for an editable text view by calling that view’s becomeFirstResponder method. Calling this method makes the target view the first responder and begins the editing process just as if the user had tapped on the view.

If your application manages several text-based views on a single screen, it is a good idea to track which view is currently the first responder so that you can dismiss the keyboard later.

Dismissing the Keyboard

Although it typically displays the keyboard automatically, the system does not dismiss the keyboard automatically. Instead, it is your application’s responsibility to dismiss the keyboard at the appropriate time. Typically, you would do this in response to a user action. For example, you might dismiss the keyboard when the user taps the Return or Done button on the keyboard or taps some other button in your application’s interface. Depending on how you configured the keyboard, you might need to add some additional controls to your user interface to facilitate the keyboard’s dismissal.

To dismiss the keyboard, you call the resignFirstResponder method of the text-based view that is currently the first responder. When a text view resigns its first responder status, it ends its current editing session, notifies its delegate of that fact, and dismisses the keyboard. In other words, if you have a variable called myTextField that points to the UITextField object that is currently the first responder, dismissing the keyboard is as simple as doing the following:

[myTextField resignFirstResponder];

Everything from that point on is handled for you automatically by the text object.

Moving Content That Is Located Under the Keyboard

When asked to display the keyboard, the system slides it in from the bottom of the screen and positions it over your application’s content. Because it is placed on top of your content, it is possible for the keyboard to be placed on top of the text object that the user wanted to edit. When this happens, you must adjust your content so that the target object remains visible.

Adjusting your content typically involves temporarily resizing one or more views and positioning them so that the text object remains visible. The simplest way to manage text objects with the keyboard is to embed them inside a UIScrollView object (or one of its subclasses like UITableView). When the keyboard is displayed, all you have to do is resize the scroll view and scroll the desired text object into position. Thus, in response to a UIKeyboardDidShowNotification, your handler method would do the following:

  1. Get the size of the keyboard.

  2. Subtract the keyboard height from the height of your scroll view.

  3. Scroll the target text field into view.

Note: As of iPhone OS 3.0, the UITableViewController class automatically resizes and repositions its table view when there is in-line editing of text fields. See “View Controllers and Navigation-Based Applications” in Table View Programming Guide for iPhone OS.

Figure 5-6 illustrates the preceding steps for a simple application that embeds several text fields inside a UIScrollView object. When the keyboard appears, the notification handler method resizes the scroll view and then uses the scrollRectToVisible:animated: method of UIScrollView to scroll the tapped text field (in this case the email field) into view.

Figure 5-6  Adjusting content to accommodate the keyboard

Adjusting content to accommodate the keyboard
Note: When setting up your own scroll views, be sure to configure the autoresizing rules for any content views appropriately. In the preceding figure, the text fields are actually subviews of a generic UIView object, which is itself a subview of the UIScrollView object. If the generic view’s UIViewAutoresizingFlexibleWidth and UIViewAutoresizingFlexibleHeight autoresizing options are set, changing the scroll view’s frame size also changes the frame of the generic view, which could yield undesirable results. Disabling these options for that view ensures that the view retains its size and its contents are scrolled correctly.

Listing 5-1 shows the code for registering to receive keyboard notifications and shows the handler methods for those notifications. This code is implemented by the view controller that manages the scroll view, and the scrollView variable is an outlet that points to the scroll view object. Each handler method gets the keyboard size from the info dictionary of the notification and adjusts the scroll view height by the corresponding amount. In addition, the keyboardWasShown: method scrolls the rectangle of the active text field, which is stored in a custom variable (called activeField in this example) that is a member variable of the view controller and set in the textFieldDidBeginEditing: delegate method, which is itself shown in Listing 5-2. (In this example, the view controller also acts as the delegate for each of the text fields.)

Listing 5-1  Handling the keyboard notifications

// Call this method somewhere in your view controller setup code.
- (void)registerForKeyboardNotifications
{
    [[NSNotificationCenter defaultCenter] addObserver:self
            selector:@selector(keyboardWasShown:)
            name:UIKeyboardDidShowNotification object:nil];
 
    [[NSNotificationCenter defaultCenter] addObserver:self
            selector:@selector(keyboardWasHidden:)
            name:UIKeyboardDidHideNotification object:nil];
}
 
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
    if (keyboardShown)
        return;
 
    NSDictionary* info = [aNotification userInfo];
 
    // Get the size of the keyboard.
    NSValue* aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
    CGSize keyboardSize = [aValue CGRectValue].size;
 
    // Resize the scroll view (which is the root view of the window)
    CGRect viewFrame = [scrollView frame];
    viewFrame.size.height -= keyboardSize.height;
    scrollView.frame = viewFrame;
 
    // Scroll the active text field into view.
    CGRect textFieldRect = [activeField frame];
    [scrollView scrollRectToVisible:textFieldRect animated:YES];
 
    keyboardShown = YES;
}
 
 
// Called when the UIKeyboardDidHideNotification is sent
- (void)keyboardWasHidden:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
 
    // Get the size of the keyboard.
    NSValue* aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
    CGSize keyboardSize = [aValue CGRectValue].size;
 
    // Reset the height of the scroll view to its original value
    CGRect viewFrame = [scrollView frame];
    viewFrame.size.height += keyboardSize.height;
    scrollView.frame = viewFrame;
 
    keyboardShown = NO;
}

The keyboardShown variable from the preceding listing is a Boolean value used to track whether the keyboard is already visible. If your interface has multiple text fields, the user can tap between them to edit the values in each one. When that happens, however, the keyboard does not disappear but the system does still generate UIKeyboardDidShowNotification notifications each time editing begins in a new text field. By tracking whether the keyboard was actually hidden, this code prevents the scroll view from being reduced in size more than once.

Listing 5-2 shows some additional code used by the view controller to set and clear the activeField variable in the preceding example. During initialization, each text field in the interface sets the view controller as its delegate. Therefore, when a text field becomes active, it calls these methods. For more information on text fields and their delegate notifications, see UITextField Class Reference.

Listing 5-2  Additional methods for tracking the active text field.

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    activeField = textField;
}
 
- (void)textFieldDidEndEditing:(UITextField *)textField
{
    activeField = nil;
}

Drawing Text

In addition to the UIKit classes for displaying and editing text, iPhone OS also includes several ways to draw text directly on the screen. The easiest and most efficient way to draw simple strings is using the UIKit additions to the NSString class. These extensions include methods for drawing strings using a variety of attributes wherever you want them on the screen. There are also methods for computing the size of a rendered string before you actually draw it, which can help you lay out your application content more precisely.

Important: Because of the performance implications, you should avoid drawing text directly whenever possible. Static text can be drawn much more efficiently using one or more UILabel objects than it can be using a custom drawing routine. Similarly, the UITextField class includes different styles that make it easier to integrate editable text areas into your content.

When you need to draw custom text strings in your interface, use the methods of NSString to do so. UIKit includes extensions to the basic NSString class that allow you to draw strings in your views. These methods allow you to adjust the position of the rendered text precisely and blend it with the rest of your view’s content. The methods of this class also let you compute the bounding rectangle for your text in advance based on the desired font and style attributes. For information, see NSString UIKit Additions Reference.

If you need more control over the fonts you plan to use during drawing, you can also use the functions of the Core Graphics framework to do your drawing. The Core Graphics frameworks provides methods for the precise drawing and placement of glyphs and text. For more information about these functions and their use, see Quartz 2D Programming Guide and Core Graphics Framework Reference.

Displaying Content in a Web View

If your user interface includes a UIWebView object, you can display local content or content that is loaded from the network. When loading local content, you can either create the content dynamically or load it from a file and display it using the loadData:MIMEType:textEncodingName:baseURL: or loadHTMLString:baseURL: method. To load content from the network, you create an NSURLRequest object and pass it to the loadRequest: method of your web view.

If, after initiating a network-based load request, you must release your web view for any reason, you must cancel the pending request before releasing the web view. You can cancel a load request using the web view’s stopLoading method. A typical place to include this code would be in the viewWillDisappear: method of the owning view controller. To determine if a request is still pending, you can check the value in the web view’s loading property.



Last updated: 2009-10-19

Did this document help you? Yes It's good, but... Not helpful...