管理文件字段和文件视图

文件字段和文件视图有多少个根本的效应:突显文本,以及允许输入和编制文本。
很多编程职务和那些回顾的靶子相关联,包罗安插文本对象、访问当前文件、检查用户的输入、以及显示覆盖视图(例如在文本字段中的书签按钮)。

UITextField大概UITextView对象的嘱托负责处理之中绝半数以上的任务。这么些委托必须选用UITextFieldDelegate或许UITextViewDelegate协议,并使内部三个或两个法子。全体协议章程都以可选完成的。为了可以调用这么些措施,你必须用编码的主意或然Interface
Builder设置文本字段和文书视图的delegate属性。

给委托发送的音讯的各样

在多数情景下,UITextField或UITextView类的实例会在给定的文书对象的首先响应者状态改变的时候发送一名目繁多名字好像的新闻给它们的寄托。当用户点击多少个文本对象,它会自行成为第3响应者;所以系统回味该公文对象出示键盘并初阶一个编纂会话。当用户点击另2个文本对象或点击按钮来终结编辑的时候,当前的文件对象注销第二响应者状态。如果没有任何文件对象被增选,系统会隐藏键盘;另一方面,如若用户拔取了另1个文书对象,它会变成第三,响应者,并且键盘会为该目标而留存。

对此一般的行事有多个例外。在平板电脑上,如若视图控制器拔取“form
sheet”样式模态突显它的视图,彰显的键盘不会熄灭,直到用户点击关闭按钮只怕模态视图控制器以编程的措施关闭。那样设计的目标是防止过多的卡通片。另2个两样是自定义输入视图。输入视图可以代表分配给文本视图或自定义视图的inputView属性的系统键盘。当有输入视图的时候,即便文本对象是第3、响应者,UI基特也足以切换键盘。

文本视图和文件字段给它们委托发送消息的依次如下:

  1. 在文书对象刚刚成为第二响应者此前——textFieldShouldBeginEditing:
    (文本字段) 和textViewShouldBeginEditing:
    (文本视图)。委托可以透过重回YES(暗中认可)或NO来校验是还是不是将文件对象变成第叁,响应者。
  2. 在文书对象刚刚成为第二响应者之后——textFieldDidBeginEditing:
    (文本字段) 和 textViewDidBeginEditing:
    (文本视图)。委托可以经过诸如履新情形音信或在编制会话时期显得覆盖视图对该消息作出响应。
  3. 在编写会话时期——当用户输入以及编辑文本的时候,文本对象调用合适的寄托方法(尽管达成)。例如,文本视图可以在文件改变时候,它的嘱托可以承受textViewDidChange:音信。文本字段可以在用于点击它的破除按钮的时候接受textFieldShouldClear:
    音讯;委托再次回到布尔值来阐明是或不是清除文本。
    落实那个方法是为了输入文本的管用。例如,假若文本应该坚守给定的格式,那么在字符串未遵循格式的时候委托应该回到NO。
  4. 在文件对象刚刚注销第壹,响应者此前——textFieldShouldEndEditing:
    (文本字段) 和 textViewShouldEndEditing:
    (文本视图)。落成这个主意的重中之重缘由是,验证输入的公文。例如,假诺文本应该符合给定的方式,倘若输入的字符串不吻合给定的形式,该委托会再次来到NO。默许情况下重返的是YES。
    连带的文本字段的办法是textFieldShouldReturn:。当用户点击回车键的时候,文本字段会发送textFieldShouldReturn:方法给委托,来打听它是不是应当撤除第2响应者。
  5. 在文书对象刚刚注销第二响应着之后————textFieldDidEndEditing:
    (文本字段) 和 textViewDidEndEditing:
    (文本视图)。委托可以兑现那个艺术来博取用户刚刚输入或编辑的文件。

文件视图和文件字段的率先响应者状态的变动,可以通过观看布告来打招呼委托以外的对象。(然则,它们不只怕获准或拒绝新景况的过渡。)布告出名字,例如UITextFieldTextDidBeginEditingNotification,
UITextViewTextDidEndEditingNotification, 和
UITextViewTextDidChangeNotification。和textFieldDidEndEditing: 和
textViewDidEndEditing:一样,观察并处理UIText菲尔德TextDidEndEditingNotification

UITextViewTextDidEndEditingNotification通告是为着访问相关的文件字段和文件视图。更加多关于通过那么些类发送的打招呼的音讯,参见UITextFieldClass Reference 和 UITextView Class Reference 。

配备文本字段和文件视图

似乎拥有由UIKit框架提供的视图对象一样,你司空眼惯须求在文书字段和文书视图呈现以前安插它们。你可以用编程格局地署它们,也足以行使在Interface
Builder中的属性检查器来配置它们。那两种艺术,你都以在装置文本对象的属性。

有一部分品质对于文本视图和文件对象是周边的,可是也有一对性质对于各个门类的目的都以一定的,包涵以下多少个:

  • 文件脾气——文本颜色、对齐方式、字体族、字体、以及字体尺寸。
  • 键盘——键盘类型、重返键名字、安全文件输入、以及自行启用的重临键,全体这几个都由此UITextInputTraits协商表明。(注意,与公事视图相关联的机动启用会车键,在点击时,它的作为和回车键一样。)更加多音信,参见“为文本对象配置键盘”。
  • 文本字段特有——边框、背景图片、禁用图片、清除按钮、以及展位文本。作为两个UIControl对象,文本字段也足以有高亮、采纳、启用、和任何质量。
  • 文本视图特有——可编制状态、数据探测器(针对电话号码和U大切诺基L连接)。因为文件视图继承自UIScrollView,你能够由此设置合适的性质个来管理滚动视图的一言一行。

钉住多个文本字段或文本视图

拥有的UITextFieldDelegate或UITextViewDelegate协议的点子,都有三个属性来分辨文本字段或文本视图第三,响应者状态的变动、值的变动、可能其余委托音讯原因的转移。若是只有1个文件对象在此时此刻的视图中突显,该公文对象通过地点的习性举行验证。不过,如若当前视图上边有两个文件字段可能文本视图,委托必须找到某种方式来指示该文件对象就是信托消息的靶子。

您可以利用以下二种艺术来规定:outlet或tag。对于outlet方法,声美赞臣(Beingmate)个outlet实例变量
(使用IBOutlet关键字),并建立3个outlet连接。在您的嘱托方法中,使用指针对照,测试传入的文本对象是还是不是与outlet提醒的靶子相同。例如,尽管你申明并延续了二个名为SSN的outlet。你的代码应该和代码清单3-1近乎。

代码清单 3-1 使用outlet识别传入的文本对象

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {

    if (textField == SSN) {

            // .....

            return NO;

        }

    return YES;

}

当你需求将字符串值写入到文本对象中,而不光是获取它们,那么为在视图中的那几个文件对象定义outlet连接尤其有用,甚至是必要的。

而对此tag格局,声Bellamy(Bellamy)组枚举常量,逐个tag对应1个常量。

enum {

    NameFieldTag = 0,

    EmailFieldTag,

    DOBFieldTag,

    SSNFieldTag

};

接下来通过编程格局大概Interface
Builder方式把整型值分配给文本对象的tag属性。(tag属性在UIView中申明了。)在委托方法中,你可以选用seitch语句来评估传入的公文对象的tag值,从而继续(如代码清单3-2所示)。

文本清单 3-2 使用tag识别传入的文书对象

- (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....

    }

}

取得输入的文本并设置文本

在用户在文件字段或文本视图中输入可能编辑文本且编辑会话停止将来,委托将取得文本,并把它存储在行使的数据模型中。对于访问输入文本的最好的信托方法是textFieldDidEndEditing:
(文本字段) 和 textViewDidEndEditing: (文本视图).

代码清单 3-3
演示了什么赢得用户在文本字段中(使用tag值来在视图中分化七个文本字段)输入的公文。UIText菲尔德大概UITextView的text属性通过文件对象持后当前展现的字符串。委托从该属性中获取字符串,并把它存储在三个字典对象中。如若该文本字段换没有字符串值(就是该字段持有二个空字符串),该信托就简单的回来。

代码清单 3-3 在文本字段中取得输入的文书

- (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;

    }

}

代码清单 3-4 展现了textViewDidEndEditing:
方法的贯彻,它从文本视图中拿走突显的字符串,并把它存储在字典中。这几个情势不须要文本视图注册为率先响应者。(resignFirstResponder方法在动作方法被调用此前被调用,该动作方法在用户在视图的用户界面上点击达成按钮的时候被调用。)

代码清单 3-4 在文书视图中拿到输入的公文

- (void)textViewDidEndEditing:(UITextView *)textView {

    NSString *theText = textView.text;

    if (![theText isEqualToString:@""]) {

        [thePerson setObject:theText forKey:MyAppPersonNotesKey];

    }

    doneButton.enabled = NO;

}

比方你须求把字符串值写入文本对象(平时在从app的数据模型检索它们之后),只要求不难的把字符串分配给文本对象的text属性即可。例如:

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

为此,给想要写入字符串的文本字段换可能文本视图(在那么些例子中时email菲尔德)定义outlet是有效的。

在文书字段使用格式化器

格式化器对象活动分析在一定格式中的字符串,并且将该字符串转换到代表数字、日期、或其余值的对象;它们还足以反操作,把NSData、NSNumber、以及近似的指标转换为表示这个对象值的格式化字符串。Foundation框架提供抽象基础类NSFormatter和五个实际子类NSDateFormatter和NSNumberFormatter。始终这么些类,用户可以在文本字段输入类似上边的值:

11/15/2010

-1,348.09

然后app可以采用formatter对象将字符串分别转换为NSData对象和NSNumber对象。

上面的代码清单,使用了日期格式化器对象的话明格式化器的施用。(当然,你可以运用UIDatePicker对象来替代文本字段输入日期,而增大日期格式化器的文本字段是另多少个增选。)代码清单3-5中的代码,创制了一个NSDateFormatter对象,并且给它分配了2个实例变量。它配备这几个日子格式化器来利用日期的“短样式”,不过在某种程度上能够响应日历、区域、以及时区的变动。它还把明日的日子分配给给定的格式作为占位字符串,以便用户在输入日期的时候有三个得以依照的模子。

代码清单 3-5 配置日期格式化器

- (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....
}

在您安插了日期格式化器之后,该信托可以调用格式化器的dateFromString:方法,来把输入的日子字符串转换为NSData对象。代码清单3-6显得了此进度。

代码清单3-6 使用NSDateFormatter对象,把日子字符串转化为多少对象

- (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;
}
}

采取了格式化器并无法确保输入的字符串必定包涵了有效值(例如,用户可以输入13看成格里高利日历的月份值)。为了有限帮忙用户输入正确的值,委托必须验证字符串,这一部分在认证输入文本中曾经表达了。因为证实平时须要已知的格式和有效值的范围,假使您想代码清单3-5那样安顿日期格式化器,以便它对于不相同的日历和区域敏感,则无从自然的领悟该格式。想要指定一个已知的日子格式,通过调用setDateFormat:来布局日期格式化器,给它传递1个透过Unicode标准定义的格式模型。

你还能将方面演示的进程反过来:把多少对象转换到通过调用NSDateFormatter的艺术stringFromDate:生成的字符串,然后把该字符串分配给文本字段、文本视图可能标签的text属性。

更多关于NSDateFormatter和NSNumberFormatter的信息,参见Data Formatting
Guide。

表明输入的文件

App有时候不只怕选用在文件字段和文书视图中输入的远非认证的字符串。恐怕该字符串必须是某种格式,也仍然该值必须在一定范围之内。验证输入字符串最好的信托方法,对于文本字段来说是textFieldShouldEndEditing:,对于文本视图来说是textViewShouldEndEditing:。那个办法在文件字段或文本视图注册为第壹响应者之前调用。再次来到NO来幸免那种景况的暴发,由此文本对象仍然是编写的严重性。若是输入的字符串是船到江心补漏迟的,你还应该呈现警告来唤醒用户这些荒唐。

代码清单3-7用到正则表明式来证实在“社会保险号码”字段中输入的字符串是还是不是合乎一定的格式。

代码清单 3-7 实用正则表明式验证文本字段的字符串格式

- (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;
}

在代码清单3-8中,落成了textViewShouldEndEditing:方法,强制限制了在文件视图中输入的公文的字符数。

代码清单 3-8 验证文本视图允许的字符串长度

- (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;
}

信托还是可以因此落实textField:shouldChangeCharactersInRange:replacementString:方法,来表明在文本字段中输入的各种字符。代码清单3-9中的代码,验证了逐个输入的字符(字符串)代表八个数字。(你能够透过给文本字段指定UIKeyboardTypeNumberPad键盘来完结均等的对象。)

代码清单 3-9 验证每一个输入的字符

- (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;
}

你可以落成textField:shouldChangeCharactersInRange:replacementString:方法,在用户输入文本的时候提供单词的大概完整性和改良效应。

在文本字段中使用覆盖视图

覆盖视图是2个布置到文本字段右边或右手的小视图。作为控件,当用户点击它们的时候,可以操作文本字段当前的情节。搜索和书签是覆盖视图的二种常见职责,然则任何也是可能的。覆盖视图可以动用文本字段中(部分)U兰德酷路泽L加载web浏览器:

想要完结覆盖视图,创建二个和文件字段中度尺寸匹配的视图,并给该视图三个老少咸宜尺寸的图片。假设该视图是三个按钮或其他空间,请指定目标对象、动作接纳器、和接触控件事件。平日来说,你期望在文本字段聚焦于编辑的时候出现覆盖视图,所以把它分配给textFieldDidBeginEditing:
委托方法中的leftView
或许rightView属性。在编排会话时期(例如在用户输入文本在此之前,或许用户刚刚开首输入文本之后),在覆盖视图出现的时候,你能够透过将UITextFieldViewMode常量分配给leftViewMode或rightViewMode属性举办控制。代码清单3-10演示了如何落到实处覆盖视图。

代码清单 3-10在文本字段中呈现覆盖视图。

- (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;
}

假设你想使用覆盖视图的上空,请确保落到实处了该动作方法。

要想移除掉覆盖视图,只要在textFieldDidEndEditing:委托方法中,将leftView可能rightView属性简单设置为nil即可。参照代码清单3-11。

代码清单 3-11移除覆盖视图

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

盯住文本视图中的所选部分

UITextViewDelegate中的方法textViewDidChangeSelection:让您可以跟踪用户在文书视图中所采用部分的修改。你可以兑现格局来博取选取一些的子字符串,并对它举行操作。代码清单3-12
是三个奇幻的例证,它让所选子字符串的字符都成为大写。

代码清单 3-12 获取选中的子字符串并转移它

- (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;
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注