UITextField使用總結
UITextField使用總結
UITextField* myTextField = [[UITextField alloc]initWithFrame:CGRectMake(50, 100, 200, 50)];
myTextField.delegate = self;//委托類需要遵守UITextFieldDelegate協議
設置屬性
UIControl屬性對UITextField完全可以用,下面的都是UITextFiels擴展的屬性:
myTextField.textAlignment = UITextAlignmentLeft;//默認就是左對齊,這個是UITextField擴展屬性
myTextField.borderStyle = UITextBorderStyleBezel;//默認是沒有邊框,如果使用了自定義的背景圖片邊框會被忽略掉
myTextField.placeholder = @"請在此輸入賬號";//為空白文本字段繪制一個灰色字符串作為占位符
myTextField.clearsOnBeginEditing = YES;//設置為YES當用點觸文本字段時,字段內容會被清除
myTextField.adjustsFontSizeToFitWidth = YES;//設置為YES時文本會自動縮小以適應文本窗口大小。默認是保持原來大小,而讓長文本滾動
//myTextField.background = [UIImage imageNamed:@"registBtn"];//可以接受UIImage對象,此項設置則邊框失效。
myTextField.clearButtonMode = UITextFieldViewModeUnlessEditing;//右邊顯示的'X'清楚按鈕
//myTextField.LeftView =
//myTextField.leftViewMode =
//myTextField.RightView =
//myTextField.rightViewMode =
這些屬性令你可以將UIView的派生類附著于為本字段的左方或右方。人們通常會將UIButton對象,比如放大鏡或者書簽按鈕附著與文本字段上。每個附著視圖都會有一個相應的模式,設置clearButtonmode屬性的那些值,同樣可以設置這個模式。
顯示
[self.view addSubview:myTextField];
委托方法
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
//返回一個BOOL值,指定是否循序文本字段開始編輯
return YES;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField{
//開始編輯時觸發,文本字段將成為first responder
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField{
//返回BOOL值,指定是否允許文本字段結束編輯,當編輯結束,文本字段會讓出first responder
//要想在用戶結束編輯時阻止文本字段消失,可以返回NO
//這對一些文本字段必須始終保持活躍狀態的程序很有用,比如即時消息
return NO;
}
- (BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
//當用戶使用自動更正功能,把輸入的文字修改為推薦的文字時,就會調用這個方法。
//這對于想要加入撤銷選項的應用程序特別有用
//可以跟蹤字段內所做的最后一次修改,也可以對所有編輯做日志記錄,用作審計用途。
//要防止文字被改變可以返回NO
//這個方法的參數中有一個NSRange對象,指明了被改變文字的位置,建議修改的文本也在其中
//同時在這里是可以做文本長度限制的判斷處理的
return YES;
}
- (BOOL)textFieldShouldClear:(UITextField *)textField{
//返回一個BOOL值指明是否允許根據用戶請求清除內容
//可以設置在特定條件下才允許清除內容
return YES;
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
//返回一個BOOL值,指明是否允許在按下回車鍵時結束編輯
//如果允許要調用resignFirstResponder方法,這回導致結束編輯,而鍵盤會被收起
[textField resignFirstResponder];//查一下resign這個單詞的意思就明白這個方法了
return YES;
}
通知
UITextField派生自UIControl,所以UIControl類中的通知系統在文本字段中也可以使用。除了UIControl類的標準事件,你還可以使用下列UITextField類特有的事件
UITextFieldTextDidBeginEditingNotification
UITextFieldTextDidChangeNotification
UITextFieldTextDidEndEditingNotification
當文本字段退出編輯模式時觸發。通知的object屬性存儲了最終文本。
因為文本字段要使用鍵盤輸入文字,所以下面這些事件發生時,也會發送動作通知
UIKeyboardWillShowNotification
鍵盤顯示之前發送
UIKeyboardDidShowNotification
鍵盤顯示之后發送
UIKeyboardWillHideNotification
鍵盤隱藏之前發送
UIKeyboardDidHideNotification
鍵盤隱藏之后發送
打開鍵盤卷動文本字段,下面附一個通用的解決鍵盤遮擋的方法
//用于處理鍵盤遮擋的問題
- (void)moveView:(UITextField *)textField leaveView:(BOOL)leave
{
UIView *accessoryView = textField.inputAccessoryView;
UIView *inputview = textField.inputView;
int textFieldY = 0;
int accessoryY = 0;
if (accessoryView && inputview)
{
CGRect accessoryRect = accessoryView.frame;
CGRect inputViewRect = inputview.frame;
accessoryY = 480 - (accessoryRect.size.height + inputViewRect.size.height);
}
else if (accessoryView)
{
CGRect accessoryRect = accessoryView.frame;
accessoryY = 480 - (accessoryRect.size.height + 216);
}
else if (inputview)
{
CGRect inputViewRect = inputview.frame;
accessoryY = 480 -inputViewRect.size.height;
}
else
{
accessoryY = 264; //480 - 216;
}
CGRect textFieldRect = textField.frame;
textFieldY = textFieldRect.origin.y + textFieldRect.size.height + 20;
int offsetY = textFieldY - accessoryY;
if (!leave && offsetY > 0)
{
int y_offset = -5;
y_offset += -offsetY;
CGRect viewFrame = self.view.frame;
viewFrame.origin.y += y_offset;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.3];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
else
{
CGRect viewFrame = CGRectMake(0, 20, 320, 460);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.3];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
}
使用如下:
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[self moveView:textField leaveView:NO];
}
- (void)textFieldDidEndEditing:(UITextField *)textField;
{
[self moveView:textField leaveView:YES];
}
下面再補充一些重寫繪制相關內容
重寫繪制行為
除了UITextField對象的風格選項,你還可以定制化UITextField對象,為他添加許多不同的重寫方法,來改變文本字段的顯示行為。這些方法都會返回一個CGRect結構,制定了文本字段每個部件的邊界范圍。如果你創見了一個自定義的UITextField類,你可以重寫這些方法,這樣就可以改變一個或多個邊界。一定不要直接調用fan廣發;它們都是被iPhone運行庫調用的回調函數下面舉個例子:
- (CGRect)clearButtonForBounds:(CGRect)bounds{
return CGRectMake(bounds.origin.x +bounds.size.width-50,
bounds.origin.y+bounds.size.height-20, 16, 16);
}
下列方法在創建一個UITextField的子類時可以重寫:
borderRectForBounds
指定矩形邊界
textRectForBounds
指定顯示文本的邊界
placeholderRectForBounds
指定站位文本的邊界
editingRectForBounds
指定編輯中文本的邊界
clearButtonRectForBounds
指定顯示清除按鈕的邊界
leftViewRectForBounds
指定顯示左附著視圖的邊界
rightViewRectForBounds
指定顯示右附著視圖的邊界
下面附帶一個UILabel和UITextField的重繪實現padding效果的代碼
首先來看 UILabel 的子類InsetsLabel 的實現代碼:
//1.header file
#import
@interface InsetsLabel : UILabel
@property(nonatomic) UIEdgeInsets insets;
-(id) initWithFrame:(CGRect)frame andInsets: (UIEdgeInsets) insets;
-(id) initWithInsets: (UIEdgeInsets) insets;
//2. implementation file
#import "InsetsLabel.h"
@implementation InsetsLabel
@synthesize insets=_insets;
-(id) initWithFrame:(CGRect)frame andInsets:(UIEdgeInsets)insets {
self = [super initWithFrame:frame];
if(self){
self.insets = insets;
}
return self;
}
-(id) initWithInsets:(UIEdgeInsets)insets {
self = [super init];
if(self){
self.insets = insets;
}
return self;
}
-(void) drawTextInRect:(CGRect)rect {
return [super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.insets)];
}
關鍵就是覆蓋了-(void) drawTextInRect: (CGRect) rect; 方法,在畫 Label 的文本時分別設置文本與 Label 四個邊的間隙,即畫在 Label 內的一個小矩形內,這個例子提供了便利的構造函數,提供自己的UIEdgeInsets 屬性。另外,函數 UIEdgeInsetsInsetRect(CGRect, UIEdgeInsets) 應該是好理解的。
再看如何設置 UITextField 中文本到四邊的間距,這里也可以定義自己的 InsetsTextField:
//
// Created by Unmi on 11/2/11.
// Copyright (c) 2011 http://unmi.cc. All rights reserved.
//
#import
@interface InsetsTextField : UITextField
@end
@implementation InsetsTextField
//控制placeHolder 的位置,左右縮20
- (CGRect)textRectForBounds:(CGRect)bounds {
return CGRectInset( bounds , 20 , 0 );
// CGRect inset = CGRectMake(bounds.origin.x + 10, bounds.origin.y, bounds.size.width - 10, bounds.size.height); //更好理解些
// return inset;
}
//控制文本的位置,左右縮 20
- (CGRect)editingRectForBounds:(CGRect)bounds {
return CGRectInset( bounds , 20 , 0 );
//CGRect inset = CGRectMake(bounds.origin.x + 10, bounds.origin.y, bounds.size.width - 10, bounds.size.height);
// return inset;
}
@end
//-----------------------------------------------------------------
//下面是使用InsetsTextField 的代碼,可放在viewDidLoad 等代理方法中
InsetsTextField *insetTextField = [[InsetsTextField alloc]
initWithFrame:CGRectMake(10, 10, 180, 25)];
//須手動設置它的borderStyle, 不然看不到邊框的
insetsTextField.borderStyle = UITextBorderStyleRoundedRect;
[self.view addSubview:insetsTextField];
[insetsTextField release];
@end
效果如下:
上面更像是借鑒的 InsetsLabel 的實現,其實對于UITextField 還有更好的實現辦法,而且更簡單,因為 UITextFiled 原來就支持的做法。比如它可以讓你做出在文本框最前方固定一個$符號,表示這個文本框是輸入錢的,第一個$是不能被刪除的。確實,你可以在 TextField 上貼個 Label,然后文本框的光標后移,稍顯麻煩了。
而UITextField 可以直接設置leftView 或rightView, 然后文本輸入區域就在leftView 和rightView 之間了,看例子:
UILabel *paddingView = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 10, 25)];
paddingView.text = @"$";
paddingView.textColor = [UIColor darkGrayColor];
paddingView.backgroundColor = [UIColor clearColor];
textfield.leftView = paddingView;
textfield.leftViewMode = UITextFieldViewModeAlways;rightView 也是一樣的設置方式,其中的 Mode 有四種,看到名字應該不難理解:
UITextFieldViewModeNever,
UITextFieldViewModeWhileEditing,
UITextFieldViewModeUnlessEditing,
UITextFieldViewModeAlways
它的效果呢就更酷了:
文本框的起始光標是從上圖數字1 位置開始的。
實際應用中,對于 UITextField 如果有類似的需求,我會毫不猶豫的使用leftView/rightView 屬性來設置。