Text编程指南(for iOS)三:管理文本字段和文本视图

Manage Text Fields and Text Views

Text fields and text views have two main functions: to display text and to enable the entry and editing of text. Several programming tasks are associated with these simple purposes, including configuring the text object, accessing the current text, validating what the user enters, and displaying overlay views such as bookmark buttons in text fields.

文本字段和文本视图有两个主要功能:显示文本并启用文本的输入和编辑。 几个编程任务与这些简单的目的相关联,包括配置文本对象,访问当前文本,验证用户输入的内容,以及在文本字段中显示遮罩视图,如书签按钮。

The delegate of a UITextField or UITextView object is responsible for most of these tasks. The delegate must adopt the UITextFieldDelegate or UITextViewDelegate protocols and implement one or more of the protocol methods. Implementation of all protocol methods is optional. To have these methods called, you must set the delegate properties of text fields and text views either programmatically or in Interface Builder.

UITextField或UITextView对象的委托对大部分这些任务负责。 代理必须采用UITextFieldDelegate或UITextViewDelegate协议并实现一个或多个协议方法。 所有协议方法的实现是可选的。 要调用这些方法,您必须以编程方式或在Interface Builder中设置文本字段和文本视图的委托属性。

The Sequence of Messages to the Delegate(代理方法序列)

In most cases, instances of the UITextField or UITextView classes send a sequence of similarly named messages to their delegates when there is a change (or impending change) in first-responder status for a given text object. When the user taps a text object, it automatically becomes first responder; as a result, the system displays the keyboard and an editing session begins for that text object. When the user taps another text object or taps a button to end editing, the current text object resigns first-responder status. If no other text object is selected, the system hides the keyboard; if, on the other hand, the user selects another text object, it becomes first responder and the keyboard for that object is displayed.

在大多数情况下,当给定文本对象的第一个响应者状态发生更改(或即将发生更改)时,UITextField或UITextView类的实例会将类似命名的消息序列发送给其代理。当用户点击文本对象时,它会自动成为第一个响应者;因此,系统显示键盘,并为该文本对象开始编辑会话。当用户点击另一个文本对象或点击一个按钮来结束编辑时,当前文本对象将重新启动第一个响应者状态。如果没有选择其他文本对象,系统会隐藏键盘;另一方面,如果用户选择另一个文本对象,则它成为第一响应者,并且显示该对象的键盘。

There are a couple of exceptions to this common behavior. On the iPad, if a view controller modally presents its view using the "form sheet" style, the keyboard, once shown, is not hidden until the user taps the dismiss key or the modal view controller is programmatically dismissed. The purpose of this behavior is to avoid excessive animations as a user moves between views that are largely, but not entirely, text fields. Another exception involves custom input views. An input view is a substitute for system keyboards that is assigned to the inputView property of a text view or a custom view. When there are input views, UIKit might swap out the keyboard even when a text object is first responder, and it might show a keyboard-like input view on the developer's behalf for non-text objects.

这种常见行为有几个例外。在iPad上,如果视图控制器使用“表单”样式来模式显示其视图,则一旦显示,键盘将不会被隐藏,直到用户点击关闭键或模式视图控制器以编程方式关闭。此行为的目的是为了避免过多的动画,因为用户在主要但并非完全是文本字段的视图之间移动。另一个例外是自定义输入视图。输入视图可替代分配给文本视图或自定义视图的inputView属性的系统键盘。当有输入视图时,即使文本对象是第一个响应者,UIKit也可能会切换键盘,并且可能会为开发人员代表非文本对象显示类似键盘的输入视图。

The sequence of messages that both text views and text fields send to their delegates is as follows:

  • Just before a text object becomes first responder—textFieldShouldBeginEditing:(text field) and textViewShouldBeginEditing:(text view).
    The delegate can verify whether the text object should become first responder by returning YES(the default) or NO.
  • Just after a text object becomes first responder—textFieldDidBeginEditing: (text field) and textViewDidBeginEditing:(text view).
    The delegate can respond to this message by updating state information or, for example, by showing an overlay view during the editing session.
  • During the editing session—various.
    While the user enters and edits text, the text object invokes certain delegation methods (if implemented). For example, the delegate of a text view can receive a textViewDidChange: message when any text changes. The delegate of a text field can receive a textFieldShouldClear: message when the user taps the clear button of a text field; the delegate returns a Boolean value indicating whether the text should be cleared.
  • Just before a text object resigns first responder—textFieldShouldEndEditing: (text field) andtextViewShouldEndEditing:(text view).
    The primary reason for a delegate to implement these methods is to validate entered text. For example, if text should conform to a given format, the delegate validates the entered string here and returns NO if the string does not conform. The default return value is YES.
    A related method for text fields is textFieldShouldReturn:. When the user taps the return key, the text field class sends a textFieldShouldReturn: message to the delegate to ask whether it should resign first responder.
  • Just after text a object resigns first responder—textFieldDidEndEditing: (text field) and textViewDidEndEditing: (text view).
    A delegate can implement these methods to get the text that the user has just entered or edited.

Text Fields 和Text View代理方法的调用步骤:

  • 在文本对象成为第一响应者之前-textFieldShouldBeginEditing:(文本字段)和textViewShouldBeginEditing :(文本视图)。
    代理可以通过返回YES(默认)或NO来验证文本对象是否应该成为第一个响应者。
  • 文本成为第一响应者 -textFieldDidBeginEditing:(文本字段)和textViewDidBeginEditing :(文本视图)。
    委托人可以通过更新状态信息或例如通过在编辑会话期间显示遮罩视图来响应该消息。
  • 在编辑期间 - 多种方法。
    当用户输入和编辑文本时,文本对象将调用某些委托方法(如果已实现)。 例如,当任何文本更改时,文本视图的委托可以接收textViewDidChange:消息。 当用户点击文本字段的清除按钮时,文本字段的代理可以接收textFieldShouldClear:消息; 委托返回一个布尔值,指示文本是否应该被清除。
  • 在文本对象首先发出响应者之前 - textFieldShouldEndEditing:(文本字段)和textViewShouldEndEditing :(文本视图)。
    委托执行这些方法的主要原因是验证输入的文本。例如,如果文本符合给定的格式,则代理将在此处验证输入的字符串,如果字符串不符合则返回NO。默认返回值为YES。
    文本字段的相关方法是textFieldShouldReturn :.当用户点击返回键时,文本字段类向代理发送一个textFieldShouldReturn:消息,询问是否应该首先响应。
  • 文本对象注销第一响应者 -textFieldDidEndEditing:(文本字段)和textViewDidEndEditing :(文本视图)。
    代理可以实现这些方法来获取用户刚刚输入或编辑的文本。

Objects other than the delegate can be informed of changes in the first-responder status of text views and text fields by observing notifications. (They can’t, however, approve or deny the transition to a new status.) The notifications have names such as UITextFieldTextDidBeginEditingNotification, UITextViewTextDidEndEditingNotification, and UITextViewTextDidChangeNotification. As with textFieldDidEndEditing: and textViewDidEndEditing:, the primary reason for observing and handling the UITextFieldTextDidEndEditingNotification andUITextViewTextDidEndEditingNotification
notifications is to access the text in the associated text field or text view. See UITextField Class Reference and UITextView Class Reference to learn more about the notifications posted by these classes.

可以通过观察通知,通知代理人以外的对象可以通知文本视图和文本字段的第一个响应者状态的更改。 (但是,它们不能批准或拒绝向新状态的转换)。通知具有诸如UITextFieldTextDidBeginEditingNotification,UITextViewTextDidEndEditingNotification和UITextViewTextDidChangeNotification之类的名称。与textFieldDidEndEditing一样:和textViewDidEndEditing :,观察和处理UITextFieldTextDidEndEditingNotification和UITextViewTextDidEndEditingNotification的主要原因
通知是访问相关文本字段或文本视图中的文本。请参阅UITextField类参考和UITextView类参考,以了解有关这些类发布的通知的更多信息。

Configuring Text Fields and Text Views(配置Text Filed 和Text Views)

As with any view object provided by the UIKit framework, you usually need to configure text fields and text views before they’re displayed. You can configure them either programmatically or using the attribute inspector of Interface Builder. In either case, you are setting a property of the text object.

与UIKit框架提供的任何视图对象一样,通常需要在显示之前配置文本字段和文本视图。 您可以通过编程方式或使用Interface Builder的属性检查器进行配置。 无论在哪种情况下,都要设置文本对象的属性。

Some properties are common to text views and text fields, and others are specific to each type of object, including the following:

  • Text characteristics—Text color, alignment, font family, font typeface, and font size.
  • Keyboard—Keyboard type, return key name, secure text entry, and auto-enabled return key, all of which are declared by theUITextInputTraits protocol. (Note that an auto-enabled return key associated with a text view acts as a carriage-return key when tapped.) For more information, see Configuring the Keyboard for Text Objects.
  • Text-field specific—Border, background image, disabled image, clear button, and placeholder text. As a UIControl
    object, text fields also have highlighted, selected, enabled, and other properties.
  • Text-view specific—Editable status, data detectors (for phone numbers and URL links). Because a text view inherits fromUIScrollView, you can also manage scroll-view behavior by setting the appropriate properties.

某些属性对于文本视图和文本字段是常见的,而其他属性对每种类型的对象都是特定的,包括以下内容:

  • 文本特征 - 文本颜色,对齐方式,字体系列,字体字体和字体大小。
  • 键盘键盘类型,返回键名称,安全文本输入和自动启用的返回键,所有这些都由UITextInputTraits协议声明。 (请注意,与文本视图相关联的自动启用的返回键在轻按时将作为回车键。)有关详细信息,请参阅为文本对象配置键盘。
  • 文本字段特定边框,背景图像,禁用图像,清除按钮和占位符文本。作为UIControl
    对象,文本字段也有突出显示,选择,启用和其他属性。
  • 特定文本视图 - 可编辑状态,数据检测器(用于电话号码和URL链接)。因为文本视图继承自UIScrollView,您还可以通过设置相应的属性来管理滚动视图行为。

Tracking Multiple Text Fields or Text Views(跟踪多个Text Fields 和Text Views)

All methods of the UITextFieldDelegate or UITextViewDelegate protocols have a parameter that identifies the text field or text view with the change in first-responder status, the change in value, or any other change that is the reason for the delegation message. If there is only one text object in the currently displayed view, the identity of the text object referenced by the parameter is obvious. However, if the currently displayed view has multiple text fields or text views, the delegate must find a way to identify the text object that is the subject of a delegation message.

UITextFieldDelegate或UITextViewDelegate协议的所有方法都有一个参数,用于标识文本字段或文本视图,其中第一个响应者状态的更改,值的更改或任何其他更改是委派消息的原因。 如果当前显示的视图中只有一个文本对象,参数引用的文本对象的标识是显而易见的。 但是,如果当前显示的视图具有多个文本字段或文本视图,则委托人必须找到一种方法来标识作为委托消息主题的文本对象。

You can make this determination using one of two approaches: outlets or tags. For the outlet approach, declare an outlet instance variable (using the IBOutlet keyword) and then make an outlet connection. In your delegation method, test whether the passed-in text object is the same object referenced by the outlet, using pointer comparison. For example, say you declare and connect an outlet named SSN. Your code might look something like Listing 3-1.

您可以使用以下两种方法之一进行此确定:outlet或tag。对于outlet方法,声明一个outlet实例变量(使用IBOutlet关键字),然后进行outlet连接。在您的委派方法中,使用指针比较来测试传入的文本对象是否是由引用引用的相同对象。例如,说你声明并连接一个名为SSN的outlet。您的代码可能如清单3-1所示。

Listing 3-1 Identifying the passed-in text object using an outlet

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
    if (textField == SSN) {
            // .....
            return NO;
        }
    return YES;
}

Defining outlet connections for the text objects in a view is especially useful, even essential, when you need to write string values to these objects, not just obtain them.
当您需要为这些对象编写字符串值时,定义视图中文本对象的outlet连接尤其有用,甚至是必需的,而不仅仅是获取它们。

For the tag approach, declare a set of enum constants, one constant for each tag.
对于标签方法,声明一组枚举常量,每个标签一个常量。

enum {
    NameFieldTag = 0,
    EmailFieldTag,
    DOBFieldTag,
    SSNFieldTag
};

Then assign the integer value to the tag property of the text object, either programmatically or in the attribute inspector of Interface Builder. (The tag property is declared by UIView.) In a delegation method, you can use a switch statement to evaluate the tag value of the passed-in text object and proceed accordingly (as shown in Listing 3-2).
然后以编程方式或在Interface Builder的属性检查器中将整数值分配给文本对象的tag属性。 (标签属性由UIView声明。)在委派方法中,您可以使用switch语句来评估传入文本对象的标签值,并相应地执行(如清单3-2所示)。

Listing 3-2 Identifying the passed-in text object using tags

- (void)textFieldDidEndEditing:(UITextField *)textField {
   switch (textField.tag) {
   case NameFieldTag:
          // do something with this text field
          break;
  case EmailFieldTag:
          // do something with this text field
          break;
    // remainder of switch statement....
  }
}

Getting the Entered Text and Setting Text(获取输入文本和设置文本)

After a user enters or edits text in a text field or text view and the editing session ends, the delegate should get the text and store it in the app’s data model. The best delegation methods for accessing entered text are textFieldDidEndEditing: (text fields) and textViewDidEndEditing: (text views).

在用户在文本字段或文本视图中输入或编辑文本,编辑会话结束后,代理应该获取文本并将其存储在应用程序的数据模型中。访问输入文本的最佳授权方法是textFieldDidEndEditing:(文本字段)和textViewDidEndEditing :(文本视图)。

Listing 3-3 illustrates how you might get text the user has entered in a text field (differentiating among multiple text fields in a view using tags). The text property of UITextField or UITextView holds the string currently displayed by the text object. The delegate gets the string from this property and stores it in a dictionary object using a key defined for each field. If the text field has no string value—that is, the field holds an empty string—the delegate simply returns.

清单3-3说明了如何获取用户在文本字段中输入的文本(使用标签区分视图中的多个文本字段)。 UITextField或UITextView的text属性保存文本对象当前显示的字符串。 委托从此属性获取字符串,并使用为每个字段定义的键将其存储在字典对象中。 如果文本字段没有字符串值,也就是说,该字段保留一个空字符串 - 代理方法返回。

Listing 3-3 Getting the text entered into a text field

- (void)textFieldDidEndEditing:(UITextField *)textField {
    if ([textField.text isEqualToString:@""])
         return;
          switch (textField.tag) {
            case NameFieldTag:
            [thePerson setObject:textField.text forKey:MyAppPersonNameKey];
            break;
        case EmailFieldTag:
            [thePerson setObject:textField.text forKey:MyAppPersonEmailKey];
            break;
        case SSNFieldTag:
            [thePerson setObject:textField.text forKey:MyAppPersonSSNKey];
            break;
        default:
            break;
    }
}

Listing 3-4 shows an implementation of the textViewDidEndEditing: method that gets the displayed string from the text view and stores it in a dictionary. Here the method doesn’t ask the text view to resign first responder. (The resignFirstResponder method was called earlier in an action method invoked when the user tapped a Done button in the view’s user interface.)

清单3-4显示了textViewDidEndEditing的一个实现:方法从文本视图中获取显示的字符串,并将其存储在字典中。 这里的方法不会要求文本视图来排除第一个响应者。 (当用户在视图的用户界面中点击了Done按钮时,ResignFirstResponder方法在调用的动作方法中被调用)。

Listing 3-4 Getting the text entered into a text view

- (void)textViewDidEndEditing:(UITextView *)textView {
    NSString *theText = textView.text;
    if (![theText isEqualToString:@""]) {
        [thePerson setObject:theText forKey:MyAppPersonNotesKey];
    }
    doneButton.enabled = NO;
}

If you need to write string values to text objects—usually after retrieving them from the app’s data model—simply assign the strings to the text property of the text object. For example:
如果您需要将字符串值写入文本对象 - 通常在从应用程序的数据模型中检索到它们之后,只需将字符串分配给文本对象的text属性即可。例如:

NSString *storedValue = [thePerson objectForKey:MyAppPersonEmailKey];
emailField.text = storedValue;

To do this, it’s useful to define outlets for each text field or text view that you want to write string values to (emailField, in this example).
为此,将要将字符串值写入的每个文本字段或文本视图定义outlets为(在此示例中为emailField)是非常有用的。

Using Formatters with Text Fields(文本格式化)

Formatter objects automatically parse strings in a specific format and convert the string to an object representing a number, date, or other value; they also work in reverse, converting NSDate, NSNumber, and similar objects to a formatted string that represents those object values. The Foundation framework provides the abstract base class NSFormatter
and two concrete subclasses of that class, NSDateFormatter and NSNumberFormatter. Using these classes, users can enter values such as the following into a text field:

11/15/2010
-1,348.09

格式化对象自动解析特定格式的字符串,并将字符串转换为表示数字,日期或其他值的对象; 它们也可以相反工作,将NSDate,NSNumber和类似对象转换为表示这些对象值的格式化字符串。 Foundation框架提供了抽象基类NSFormatter
和该类的两个具体子类,NSDateFormatter和NSNumberFormatter。 使用这些类,用户可以在文本字段中输入以下值:

11/15/2010
-1,348.09

And your app can use formatter objects to convert the strings into an NSDate object and an NSNumber object, respectively.
而您的应用程序可以使用格式化对象将字符串分别转换为NSDate对象和NSNumber对象。

The following code listings use a date-formatter object to illustrate the use of formatters. (Of course, you could use a UIDatePicker object for date input rather than a text field, but a text field with an attached date formatter is another option.) The code in Listing 3-5creates an NSDateFormatter object and assigns it to an instance variable. It configures the date formatter to use the “short style” for dates, but in a way that is responsive to changes in calendar, locale, and time zone. It also assigns today’s date in the given format as a placeholder string so that users have a model to follow when they enter dates.
以下代码清单使用date-formatter对象来说明使用格式化程序。 (当然,您可以使用UIDatePicker对象进行日期输入而不是文本字段,但是带有附加日期格式化程序的文本字段是另一个选项。)清单3-5中的代码创建了一个NSDateFormatter对象并将其分配给一个实例变量。 它配置日期格式化程序以使用日期的“简短样式”,但是可以响应日历,区域设置和时区的更改。 它还将给定格式的今天的日期作为占位符字符串进行分配,以便用户在输入日期时具有遵循的模型。

Listing 3-5 Configuring a date formatter

- (void)viewDidLoad {
    [super viewDidLoad];
    dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setGeneratesCalendarDates:YES];
    [dateFormatter setLocale:[NSLocale currentLocale]];
    [dateFormatter setCalendar:[NSCalendar autoupdatingCurrentCalendar]];
    [dateFormatter setTimeZone:[NSTimeZone defaultTimeZone]];
    [dateFormatter setDateStyle:NSDateFormatterShortStyle]; // example: 4/13/10
    DOB.placeholder = [NSString stringWithFormat:@"Example: %@", [dateFormatter stringFromDate:[NSDate date]]];
 
    // code continues....
}

After you have configured the date formatter, the delegate can call the dateFromString: method on the formatter to convert the entered date string into an NSDate object, as shown in Listing 3-6.
配置日期格式化程序后,代理可以调用格式化程序上的dateFromString:方法将输入的日期字符串转换为NSDate对象,如清单3-6所示。

Listing 3-6 Using an NSDateFormatter
object to convert a date string to a date object

- (void)textFieldDidEndEditing:(UITextField *)textField {
    [textField resignFirstResponder];
    if ([textField.text isEqualToString:@""])
        return;
    switch (textField.tag) {
        case DOBField:
            NSDate *theDate = [dateFormatter dateFromString:textField.text];;
            if (theDate)
                [inputData setObject:theDate forKey:MyAppPersonDOBKey];
            break;
        // more switch case code here...
        default:
            break;
    }
}

The use of formatters does not guarantee that the entered string contains valid values—for example, a user could enter 13 for a month number in the Gregorian calendar. To ensure that the user has entered a correct value, the delegate must validate the string as explained in Validating Entered Text. And because validation often requires a known format and range of valid values, if you configure the date formatter as in Listing 3-5 so that it is sensitive to different calendars and locales, the format cannot be known with certainty. To specify a known date format, configure the date formatter by calling setDateFormat:, passing in a format pattern defined by the Unicode standard.

使用格式化程序不能保证输入的字符串包含有效值 - 例如,用户可以输入13在公历中有一个月的数字。 为了确保用户输入正确的值,委托必须验证字符串,如验证输入的文本中所述。 并且因为验证通常需要一个已知的格式和范围的有效值,如果您将清单3-5中的日期格式化程序配置为使其对不同的日历和区域设置敏感,则无法确定该格式。 要指定已知的日期格式,请通过调用setDateFormat:传递由Unicode标准定义的格式模式来配置日期格式化程序。

You can also reverse the procedure shown above: Convert a date object to a string in a given format by calling the NSDateFormatter method stringFromDate: and then assign that string to the text property of a text field, text view, or label.
您还可以反转上述过程:通过调用NSDateFormatter方法stringFromDate将日期对象转换为给定格式的字符串,然后将该字符串分配给文本字段,文本视图或标签的text属性。

For more information on NSDateFormatter and NSNumberFormatter, see Data Formatting Guide.

有关NSDateFormatter和NSNumberFormatter的更多信息,请参见数据格式指南。

Validating Entered Text(验证输入文本)

An app sometimes cannot accept the strings entered in text fields and text views without validating the value first. Perhaps the string must be in a certain format, or the value (after it is converted to a numeric value) must fall within a certain range. The best delegationmethods for validating entered strings are textFieldShouldEndEditing: for text fields and textViewShouldEndEditing: for text views. These methods are called just before the text field or text view resigns first responder status. Returning NO prevents that from happening, and consequently the text object remains the focus of editing. If an entered string is invalid, you should also display an alert to inform the user of the error.

应用程序有时无法接受在文本字段和文本视图中输入的字符串,而不首先验证该值。也许字符串必须是某种格式,或者值(转换为数值后)必须在一定范围内。验证输入字符串的最佳代理方法是textFieldShouldEndEditing:用于文本字段和textViewShouldEndEditing:用于文本视图。这些方法在文本字段或文本视图之前就会调用第一个响应者状态。返回否防止发生,因此文本对象仍然是编辑的焦点。如果输入的字符串无效,您还应该显示警告以通知用户错误。

Listing 3-7 uses a regular expression to verify that the string entered in a “Social Security Number” field conforms to the format for such numbers.
清单3-7使用正则表达式来验证“Social Security Number”字段中输入的字符串是否符合这些数字的格式。

Listing 3-7 Validating the format of a text field’s string using a regular expression

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
    if (textField == SSN) { // SSN is an outlet
        NSString *regEx = @"[0-9]{3}-[0-9]{2}-[0-9]{4}";
        NSRange r = [textField.text rangeOfString:regEx options:NSRegularExpressionSearch];
        if (r.location == NSNotFound) {
            UIAlertView *av = [[[UIAlertView alloc] initWithTitle:@"Entry Error"
                message:@"Enter social security number in 'NNN-NN-NNNN' format"
                delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
            [av show];
            return NO;
        }
    }
        return YES;
}

The implementation of textViewShouldEndEditing: in Listing 3-8 enforces a character limit for the text entered in a text view.
textViewShouldEndEditing:在清单3-8中的实现强制在文本视图中输入的文本的字符数限制。

Listing 3-8 Validating a text view’s string for allowable length

- (BOOL)textViewShouldEndEditing:(UITextView *)textView {
      if (textView.text.length > 50) {
        UIAlertView *av = [[[UIAlertView alloc] initWithTitle:@"Entry Error"
            message:@"You must enter less than 50 characters." delegate:self cancelButtonTitle:@"OK"
            otherButtonTitles:@"Clear", nil] autorelease];
        [av show];
        return NO;
    }
    return YES;
}

The delegate can also validate each character as it is entered into a text field by implementing the textField:shouldChangeCharactersInRange:replacementString:
method. The code in Listing 3-9 verifies that each entered character (string) represents a digit. (You could accomplish the same goal by specifying a UIKeyboardTypeNumberPad keyboard for the text field.)
代理还可以通过实现textField验证每个输入到文本字段的字符:shouldChangeCharactersInRange:replacementString:
方法。清单3-9中的代码验证每个输入的字符(字符串)代表数字。 (您可以通过为文本字段指定一个UIKeyboardTypeNumberPad键盘来实现相同的目标。)

Listing 3-9 Validating each character as it’s entered

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string {
  if ([string isEqualToString:@""]) return YES;
  if (textField.tag == SalaryFieldTag) {
    unichar c = [string characterAtIndex:0];
     if ([[NSCharacterSet decimalDigitCharacterSet] characterIsMember:c]) {
        return YES;
      } else {
         return NO;
      }
    }
  return YES;
}

You can also implement the textField:shouldChangeCharactersInRange:replacementString: method to offer possible word completions or corrections to the user as they enter text.
您还可以实现textField:shouldChangeCharactersInRange:replacementString:方法,以便在用户输入文本时提供可能的单词完成或更正。

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:

遮罩视图是插入文本字段的左右角的小视图。当用户点击它们(通常是按钮)时,它们作为控件,并对文本字段的当前内容执行操作。搜索和书签是遮罩视图的两个常见任务,但其他可能。此遮罩视图使用文本字段中的(部分)URL加载Web浏览器:

To implement an overlay view, create a view of a size that fits within the height of the text field and give the view an appropriately sized image. If the view is a button or other control, specify a target object, an action selector, and the triggering control events. Usually you want an overlay view to appear when its text field is the focus of editing, so assign it to the text field’s leftView or rightView property in the delegate’s textFieldDidBeginEditing: method. You can control when an overlay view appears during the editing session—for example, before the user begins entering text or only after the user begins entering text—by assigning a UITextFieldViewMode constant to the leftViewMode or rightViewMode property. Listing 3-10 illustrates how you might implement an overlay view.

要实现遮罩视图,请创建适合文本字段高度的大小视图,并为视图提供适当大小的图像。 如果视图是按钮或其他控件,请指定目标对象,动作选择器和触发控制事件。 通常,当文本字段是编辑的焦点时,您希望出现遮罩视图,因此将其分配给代理的textFieldDidBeginEditing:方法中的文本字段的leftView或rightView属性。 您可以在编辑会话期间控制遮罩视图何时出现,例如,在用户开始输入文本之前,或者仅在用户开始输入文本之后 - 通过将UITextFieldViewMode常量分配给leftViewMode或rightViewMode属性。 清单3-10说明了如何实现遮罩视图。

Listing 3-10 Displaying an overlay view in a text field

- (void)textFieldDidBeginEditing:(UITextField *)textField {
     if (textField.tag == NameField && self.overlayButton) {
        textField.leftView = self.overlayButton;
        textField.leftViewMode = UITextFieldViewModeAlways;
    }
}
 
@dynamic overlayButton;
 
- (UIButton *)overlayButton {
    if (!overlayButton) {
        overlayButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
        UIImage *overlayImage = [UIImage imageNamed:@"bookmark.png"];
        if (overlayImage) {
            [overlayButton setImage:overlayImage forState:UIControlStateNormal];
            [overlayButton addTarget:self action:@selector(bookmarkTapped:)
                forControlEvents:UIControlEventTouchUpInside];
        }
    }
    return overlayButton;
}

If you use a control for an overlay view, be sure to implement the action method.
如果您使用有遮罩视图的控件,请务必实现这个操作方法。

To remove an overlay view, simply set the leftView or rightView property to nil in the textFieldDidEndEditing: delegation method, as in Listing 3-11.
要删除遮罩视图,只需在textFieldDidEndEditing:delegate方法中将leftView或rightView属性设置为nil,如清单3-11所示。

Listing 3-11 Removing the overlay view

- (void)textFieldDidEndEditing:(UITextField *)textField {
  if (textField.tag == NameFieldTag) {
    textField.leftView = nil;
  }
  // remainder of implementation....
}

Tracking the Selection in Text Views(跟踪文本视图中被选择内容)

The textViewDidChangeSelection: method of UITextViewDelegate lets you track changes to the selections that a user makes in a text view. You can implement the method to obtain the selected substring and do something with it. Listing 3-12 is a whimsical example that makes all characters in the selected substring uppercase.

UITextViewDelegate的textViewDidChangeSelection:method可以跟踪用户在文本视图中进行的选择的更改。 您可以实现该方法来获取所选的子字符串,然后使用它。 清单3-12是一个简略的示例,它使所选字符串中的所有字符大写。

Listing 3-12 Getting the selected substring and changing it

- (void)textViewDidChangeSelection:(UITextView *)textView {
  NSRange r = textView.selectedRange;
  if (r.length == 0) {  return;  }

  NSString *selText = [textView.text substringWithRange:r];
  NSString *upString = [selText uppercaseString];
  NSString *newString = [textView.text stringByReplacingCharactersInRange:r withString:upString];
  textView.text = newString;
}

你可能感兴趣的:(Text编程指南(for iOS)三:管理文本字段和文本视图)