[Text Relatives]
With TextKit the resources at your disposal range from framework objects—such as text views, text fields, and web views—to text layout engines that you can use directly to draw, lay out, and otherwise manage text. Underlying the text views in UIKit is a powerful layout engine called Text Kit.
TextKit 让为我们提供了各种objects以及layout engine(渲染排版用). 下图是常用排版术语:
The UIKit framework provides three primary classes for displaying this text content in an app’s user interface:
-
UILabel
defines a label, which displays a static text string. -
UITextField
defines a text field, which displays a single line of editable text. -
UITextView
defines a text view, which displays multiple lines of editable text.
Labels and text fields are intended to be used for relatively small amounts of text, typically a single line. Text views, on the other hand, are meant to display large amounts of text. When working with editable text fields and text views, you should always provide a delegate object to manage the editing session. Text views send several differentnotifications to the delegate to let them know when editing begins, when it ends, and to give them a chance to override some editing actions.
Characters and glyphs do not have a one-to-one correspondence. In some cases a character may be represented by multiple glyphs, such as an “é” which may be an “e” glyph combined with an acute accent glyph “´”. In other cases, a single glyph may represent multiple characters, as in the case of a ligature, or joined letter. Figure 2-2 shows individual characters and the single-glyph ligature often used when they are adjacent.
The glyphs used to depict characters are selected by the layout manager during composition and layout processing. The layout manager determines which glyphs to use and where to place them in the display, or view. The layout manager caches the glyph codes in use and provides methods to convert between characters and glyphs and between characters and view coordinates.
[The Sequence of Messages to the Delegate]
The following code listings use a date-formatter object to illustrate the use of formatters.
1 - (void)viewDidLoad { 2 [super viewDidLoad]; 3 dateFormatter = [[NSDateFormatter alloc] init]; 4 [dateFormatter setGeneratesCalendarDates:YES]; 5 [dateFormatter setLocale:[NSLocale currentLocale]]; 6 [dateFormatter setCalendar:[NSCalendar autoupdatingCurrentCalendar]]; 7 [dateFormatter setTimeZone:[NSTimeZone defaultTimeZone]]; 8 [dateFormatter setDateStyle:NSDateFormatterShortStyle]; // example: 4/13/10 9 DOB.placeholder = [NSString stringWithFormat:@"Example: %@", [dateFormatter stringFromDate:[NSDate date]]]; 10 11 // code continues.... 12 }
Using an NSDateFormatter
object to convert a date string to a date object.
1 - (void)textFieldDidEndEditing:(UITextField *)textField { 2 [textField resignFirstResponder]; 3 if ([textField.text isEqualToString:@""]) 4 return; 5 switch (textField.tag) { 6 case DOBField: 7 NSDate *theDate = [dateFormatter dateFromString:textField.text];; 8 if (theDate) 9 [inputData setObject:theDate forKey:MyAppPersonDOBKey]; 10 break; 11 // more switch case code here... 12 default: 13 break; 14 } 15 }
[Using Overlay Views in Text Fields]
Overlay views are small views inserted into the left and right corners of a text field. They act as controls when users tap them (frequently they are buttons) and act on the current contents of the text field. Searching and bookmarking are two common tasks for overlay views, but others are possible. This overlay view loads a web browser using the (partial) URL in the text field:
Displaying an overlay view in a text field:
1 - (void)textFieldDidBeginEditing:(UITextField *)textField { 2 if (textField.tag == NameField && self.overlayButton) { 3 textField.leftView = self.overlayButton; 4 textField.leftViewMode = UITextFieldViewModeAlways; 5 } 6 } 7 8 @dynamic overlayButton; 9 10 - (UIButton *)overlayButton { 11 if (!overlayButton) { 12 overlayButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain]; 13 UIImage *overlayImage = [UIImage imageNamed:@"bookmark.png"]; 14 if (overlayImage) { 15 [overlayButton setImage:overlayImage forState:UIControlStateNormal]; 16 [overlayButton addTarget:self action:@selector(bookmarkTapped:) 17 forControlEvents:UIControlEventTouchUpInside]; 18 } 19 } 20 return overlayButton; 21 }
[Displaying Web Content]
Loading a local PDF file into the web view:
1 - (void)viewDidLoad { 2 [super viewDidLoad]; 3 4 NSString *thePath = [[NSBundle mainBundle] pathForResource:@"iPhone_User_Guide" ofType:@"pdf"]; 5 if (thePath) { 6 NSData *pdfData = [NSData dataWithContentsOfFile:thePath]; 7 [(UIWebView *)self.view loadData:pdfData MIMEType:@"application/pdf" 8 textEncodingName:@"utf-8" baseURL:nil]; 9 } 10 }
The web-view delegate managing network loading:
1 - (void)webViewDidStartLoad:(UIWebView *)webView 2 { 3 // starting the load, show the activity indicator in the status bar 4 [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; 5 } 6 7 - (void)webViewDidFinishLoad:(UIWebView *)webView 8 { 9 // finished loading, hide the activity indicator in the status bar 10 [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 11 } 12 13 - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error 14 { 15 // load error, hide the activity indicator in the status bar 16 [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 17 18 // report the error inside the webview 19 NSString* errorString = [NSString stringWithFormat: 20 @"<html><center><font size=+5 color='red'> 21 An error occurred:<br>%@</font></center></html>", 22 error.localizedDescription]; 23 [self.myWebView loadHTMLString:errorString baseURL:nil]; 24 }
[Managing the Keyboard]
The UITextField
and UITextView
classes both conform to theUITextInputTraits
protocol, which defines the properties for configuring the keyboard. When the keyboard is shown or hidden, iOS sends out the following notifications to any registered observers:
When asked to display the keyboard, the system slides it in from the bottom of the screen and positions it over your app’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.
[Copy, Cut, and Paste Operations]
Several classes and an informal protocol of the UIKit framework give you the methods and mechanisms you need to implement copy, cut, and paste operations in your app:
-
The
UIPasteboard
class provides pasteboards: protected areas for sharing data within an app or between apps. The class offers methods for writing and reading items of data to and from a pasteboard. -
The
UIMenuController
class displays an edit menu above or below the selection to be copied, cut, or pasted into. The default commands of the edit menu are (potentially) Copy, Cut, Paste, Select, and Select All. You can also add custom menu items to the edit menu (see “Adding Custom Items to the Edit Menu”). -
The
UIResponder
class declares the methodcanPerformAction:withSender:
. Responder classes can implement this method to show and remove commands of the edit menu based on the current context. -
The
UIResponderStandardEditActions
informal protocol declares the interface for handling copy, cut, paste, select, and select-all commands. When users tap one of the commands in the edit menu, the correspondingUIResponderStandardEditActions
method is invoked.
Pasteboards may be public or private. Public pasteboards are called system pasteboards; private pasteboards are created by apps, and hence are called app pasteboards. Pasteboards must have unique names. UIPasteboard
defines two system pasteboards, each with its own name and purpose:
-
UIPasteboardNameGeneral
is for cut, copy, and paste operations involving a wide range of data types. You can obtain a singleton object representing the General pasteboard by invoking thegeneralPasteboard
class method. -
UIPasteboardNameFind
is for search operations. The string currently typed by the user in the search bar (UISearchBar
) is written to this pasteboard, and thus can be shared between apps. You can obtain an object representing the Find pasteboard by calling thepasteboardWithName:create:
class method, passing inUIPasteboardNameFind
for the name.
Typically you use one of the system-defined pasteboards, but if necessary you can create your own app pasteboard using pasteboardWithName:create:
If you invoke pasteboardWithUniqueName
, UIPasteboard
gives you a uniquely-named app pasteboard. You can discover the name of a pasteboard through its name
property.