根據項目需求,在項目中許多地方都要用到TextField用于接受用戶的輸入,而且這些文本框全部都是統一的自定義樣式。這樣一來根本不可能使用系統的輸入框,而且項目中多個界面的都有輸入框,我們也不可能每個界面的每個輸入框都去設計一遍,所以做了一個自定義的TextField。在某個頁面添加多個自定義的TextField,編輯不同的TextField,當所有的TextField全部都有內容的時候,頁面中的按鈕變為可以點擊狀態,如果存在某一個文本框為空,則按鈕為禁用狀態。代碼很簡單,使用也很簡單,可以先看效果圖。
一、效果圖:
QQ20180402-141926-HD.gif
1.主要實現的效果是:
- 當輸入框內沒有內容時,輸入框左側的圖標是“鉛筆”,表示用戶需要進行編輯。
- 當輸入框內有文本時,圖標變成“笑臉”,表示用戶輸入了內容。
- 當頁面的所有文本框有內容時,下邊的“完成”按鈕為可以點擊狀態。
- 當頁面的文本框有一個內容為空時,下邊的“完成”按鈕為就是禁用狀態。
2.主要實現原理:
自定義的輸入框繼承系統的UITextField,初始化時提供默認樣式。
在自定義文本框內實現UITextFieldDelegate的方法- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;
在該方法內實時判斷用戶是否輸入了內容,如果有內容則改變輸入框樣式為選中狀態,如果沒有內容則改變輸入框樣式為默認樣式。同時要在該方法內實時調用自定義文本框的委托方法- (void)textFieldChangedText:(MyTextField *)myTextField;
,該方法在添加多個文本框的頁面實現,根據文本框的是否存在內容來改變按鈕的狀態。
二、自定義TextField的代碼:
1: .h文件
#import <UIKit/UIKit.h>
@protocol MyTextFieldDelegate;
@interface MyTextField : UITextField
@property (nonatomic, weak) id<MyTextFieldDelegate> textFieldDelegate;
@property (nonatomic) BOOL textIsEmpty; //文本是否為空
@end
@protocol MyTextFieldDelegate<NSObject>
- (void)textFieldChangedText:(MyTextField *)myTextField;
@end
2: .m文件
@interface MyTextField() <UITextFieldDelegate>
@end
@implementation MyTextField
#pragma mark - Override
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
[self initialize];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self initialize];
}
return self;
}
- (void)setPlaceholder:(NSString *)placeholder {
NSDictionary *attributes = @{
NSFontAttributeName : [UIFont systemFontOfSize:16],
NSForegroundColorAttributeName : [UIColor grayColor]
};
NSAttributedString *attributedPlaceholder = [[NSAttributedString alloc] initWithString:placeholder attributes:attributes];
self.attributedPlaceholder = attributedPlaceholder;
}
#pragma mark- UITextFieldDelegate
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSMutableString * changedString=[[NSMutableString alloc] initWithString:textField.text];
[changedString replaceCharactersInRange:range withString:string];
if (changedString.length == 0) {
self.textIsEmpty = YES;
[self setNormalStyle];
}else{
self.textIsEmpty = NO;
[self setSelectedStyle];
}
// 實時監測文本框的編輯狀態
if ([self.textFieldDelegate respondsToSelector:@selector(textFieldChangedText:)]) {
[self.textFieldDelegate textFieldChangedText:self];
}
return YES;
}
#pragma mark - Private
- (void)initialize {
/**
阻止鍵盤自動聯想,如果沒有這句話,想要實現這樣的效果就不能用這樣的方式了,
需要監聽UITextFieldTextDidChangeNotification通知來做,
有需要的可以留言,我再發一個阻止鍵盤聯想的情況下如何實現這樣效果的代碼
*/
self.autocorrectionType = UITextAutocorrectionTypeNo;
self.textIsEmpty = self.text.length == 0;
self.delegate = self;
self.font = [UIFont systemFontOfSize:16];
self.textColor = [UIColor B1Color];
[self setNormalStyle];
}
- (void)setNormalStyle {
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"textfield_pen_icon"]];
imageView.contentMode = UIViewContentModeLeft;
self.leftView = imageView;
self.leftView.width = 30;
self.leftViewMode = UITextFieldViewModeAlways;
[self drawBottomBorder:1 color:[UIColor B5Color]];
}
- (void)setSelectedStyle {
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"textfield_smile_icon"]];
imageView.contentMode = UIViewContentModeLeft;
self.leftView = imageView;
self.leftView.width = 30;
self.leftViewMode = UITextFieldViewModeAlways;
[self drawBottomBorder:1 color:[UIColor P2Color]];
}
@end
三、使用:
1.代碼中使用方式:在要展示的viewController中添加就好
#pragma mark - Override
- (void)viewDidLoad {
[super viewDidLoad];
self.userNameTextField = [[MyTextField alloc] initWithFrame:CGRectMake(30, 50, self.view.bounds.size.width - 60, 35)];
self.userNameTextField.placeholder = @"請輸入用戶名";
[self.view addSubview:self.userNameTextField];
self.passwordTextField = [[MyTextField alloc] initWithFrame:CGRectMake(30, 100, self.view.bounds.size.width - 60, 35)];
self.passwordTextField.placeholder = @"請輸入密碼";
[self.view addSubview:self.passwordTextField];
self.userNameTextField.textFieldDelegate = self;
self.passwordTextField.textFieldDelegate = self;
[self setButtonState]; //viewDidLoad中調用表示初始化按鈕的狀態
}
#pragma mark - MyTextFieldDelegate
// 實現自定義文本框的委托方法
- (void)textFieldChangedText:(MyTextField *)myTextField {
[self setButtonState];
}
#pragma mark - Private
- (void)setButtonState {
if (!self.userNameTextField.textIsEmpty && !self.passwordTextField.textIsEmpty) {
self.sigininButton.userInteractionEnabled = YES;
self.sigininButton.alpha = 1;
} else {
self.sigininButton.userInteractionEnabled = NO;
self.sigininButton.alpha = 0.5;
}
}
@end
2.Nib使用方式:
- 拖動一個UITextField控件到View上,將它的class標識為MyTextField,取消邊框,根據自己需求輸入placeholder
步驟1
步驟2
好了,自定義完畢,使用也超級簡單。如果能幫助到有一樣問題的小伙伴,我很高興,祝大家工作順利。