iOS开发之UI篇(8)—— UITextField

版本
Xcode 9.1

基本用法

继承关系:

UITextField : UIControl : UIView : UIResponder : NSObject

示例:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.view.backgroundColor = [UIColor lightGrayColor];

    /* ----- 初始化 ----- */
    UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 100, 300, 30)];
    textField.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2, 100);     // 居中
    [self.view addSubview:textField];   // 添加至self.view

    /* ----- 常用属性 ----- */

    // 设置背景颜色
    textField.backgroundColor = [UIColor whiteColor];
    textField.layer.cornerRadius = 10;

    // 设置文字内容
    textField.text = @"看影成痴";
    // 设置字体颜色
    textField.textColor = [UIColor purpleColor];
    // 设置字体样式及大小
    textField.font = [UIFont systemFontOfSize:18.0];
    // 设置对齐方式
    textField.textAlignment = NSTextAlignmentCenter;
    // 设置边框的样式(cornerRadius将无效)
    textField.borderStyle = UITextBorderStyleRoundedRect;
    // 设置提示文字
    textField.placeholder = @"请输入用户名";

    // 设置清空模式,是否每次编辑时都清空一下
    textField.clearsOnBeginEditing = YES;
    // 自动适应输入框宽度,让输入框可以显示输入的一定数量的所有字体
    textField.adjustsFontSizeToFitWidth = YES;
    // 设置文字显示的最小字体大小
    textField.minimumFontSize = 12;

    // 设置可用状态的背景图片(拉伸)
    textField.background = [UIImage imageNamed:@""];
    // 设置不可用状态的背景图片(拉伸)
    textField.disabledBackground = [UIImage imageNamed:@""];

    // 设置清理按钮模式
    textField.clearButtonMode = UITextFieldViewModeWhileEditing;
    // 设置输入框左图
    textField.leftView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"left.png"]];
    textField.leftView.bounds = CGRectMake(0, 0, 30, 30);
    // 左图显示模式(编辑时不显示)
    textField.leftViewMode = UITextFieldViewModeUnlessEditing;
    // 设置输入框右图
    textField.rightView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"right.png"]];
    textField.rightView.bounds = CGRectMake(0, 0, 30, 30);
    // 右图显示模式
    textField.rightViewMode = UITextFieldViewModeUnlessEditing;

    // 是否密文输入(输入内容是否可见)
    textField.secureTextEntry = NO;
    // 设置键盘外观
    textField.keyboardAppearance = UIKeyboardAppearanceDark;
    // 设置键盘类型
    textField.keyboardType = UIKeyboardTypeNumberPad;
    // 设置返回键类型
    textField.returnKeyType = UIReturnKeyRoute;
    // 设置首字母是否大写
    textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
    // 是否自动修正输入内容
    textField.autocorrectionType = UITextAutocorrectionTypeDefault;
}

示例效果:


示例中的一些属性枚举:

/* 文字对齐方式 */
typedef NS_ENUM(NSInteger, NSTextAlignment) {
    NSTextAlignmentLeft      = 0,    // 左对齐
#if TARGET_OS_IPHONE                 // 判断真机or模拟器,我们只管枚举值对应的对齐方式即可
    NSTextAlignmentCenter    = 1,    // 居中(真机)
    NSTextAlignmentRight     = 2,    // 右对齐(真机)
#else /* !TARGET_OS_IPHONE */
    NSTextAlignmentRight     = 1,    // 右对齐(真机)
    NSTextAlignmentCenter    = 2,    // 居中(真机)
#endif
    NSTextAlignmentJustified = 3,    // 最后一行和段落对齐
    NSTextAlignmentNatural   = 4,    // 默认对齐脚本
} NS_ENUM_AVAILABLE_IOS(6_0);


/* 边框样式 */
typedef NS_ENUM(NSInteger, UITextBorderStyle) {
    UITextBorderStyleNone,           // 默认样式,无边框
    UITextBorderStyleLine,           // 边框加黑色线条
    UITextBorderStyleBezel,          // 边框加灰色线条,上边和左边加重
    UITextBorderStyleRoundedRect     // 圆角 
};


/* 某个属性(譬如删除按钮,leftView)出现时机 */
typedef NS_ENUM(NSInteger, UITextFieldViewMode) {
    UITextFieldViewModeNever,        // 从不出现
    UITextFieldViewModeWhileEditing, // 编辑时出现
    UITextFieldViewModeUnlessEditing,// 非编辑时出现
    UITextFieldViewModeAlways        // 总是出现
};


/* ----- 以下是与 输入内容or键盘 相关属性枚举 ----- */

/* 自动修正内容 */
typedef NS_ENUM(NSInteger, UITextAutocorrectionType) {
    UITextAutocorrectionTypeDefault, // 默认,可自动修正
    UITextAutocorrectionTypeNo,      // 不可修正
    UITextAutocorrectionTypeYes,     // 可自动修正
};


/* 首字母大写 */
typedef NS_ENUM(NSInteger, UITextAutocapitalizationType) {
    UITextAutocapitalizationTypeNone,          // 不自动大写
    UITextAutocapitalizationTypeWords,         // 单词首字母大写
    UITextAutocapitalizationTypeSentences,     // 句子首字母大写 
    UITextAutocapitalizationTypeAllCharacters, // 所有字母均大写
};


/* 键盘外观 */
typedef NS_ENUM(NSInteger, UIKeyboardAppearance) {
    UIKeyboardAppearanceDefault,          // 默认外观,浅灰色
    UIKeyboardAppearanceDark,             // 深灰色
    UIKeyboardAppearanceLight,            // 浅灰色
    UIKeyboardAppearanceAlert,            // 深灰色(已弃用)
};


/* 键盘类型 */
typedef NS_ENUM(NSInteger, UIKeyboardType) {
    UIKeyboardTypeDefault,                // 默认键盘,支持所有字符
    UIKeyboardTypeASCIICapable,           // ASCII类型
    UIKeyboardTypeNumbersAndPunctuation,  // 电话类型,支持+*#
    UIKeyboardTypeURL,                    // URL类型支持 . / .com
    UIKeyboardTypeNumberPad,              // A number pad with locale-appropriate digits (0-9, ۰-۹, ०-९, etc.). Suitable for PIN entry.
    UIKeyboardTypePhonePad,               // 电话类型 ,支持0-9, * , #
    UIKeyboardTypeNamePhonePad,           // 电话类型,支持输入人名
    UIKeyboardTypeEmailAddress,           // 电子邮件类型,支持空格 @ . 邮件地址
    UIKeyboardTypeDecimalPad,             // 数字键盘,支持小数点
    UIKeyboardTypeTwitter,                // 为twitter优化的键盘,更容易输入@ #
    UIKeyboardTypeWebSearch,              // 为URL优化的键盘,支持空格 . 地址
    UIKeyboardTypeASCIICapableNumberPad,  // 数字键盘,总是ASCII数字类型(iOS 10.0开始引入)
    UIKeyboardTypeAlphabet,               // 已弃用
};


/* 键盘的返回键类型 */
typedef NS_ENUM(NSInteger, UIReturnKeyType) {
    UIReturnKeyDefault,                   // 默认,标有Return的灰色按钮
    UIReturnKeyGo,                        // 标有Go的蓝色按钮
    UIReturnKeyGoogle,                    // 标有Google的蓝色按钮
    UIReturnKeyJoin,                      // 标有Join的蓝色按钮
    UIReturnKeyNext,                      // 标有Next的蓝色按钮
    UIReturnKeyRoute,                     // 标有Route的蓝色按钮
    UIReturnKeySearch,                    // 标有Search的蓝色按钮
    UIReturnKeySend,                      // 标有Send的蓝色按钮
    UIReturnKeyYahoo,                     // 标有Yahoo的蓝色按钮
    UIReturnKeyDone,                      // 标有Done的蓝色按钮
    UIReturnKeyEmergencyCall,             // 紧急呼叫按钮
    UIReturnKeyContinue ,                 // 标有Continue的灰色按钮(iOS9.0开始引入)
};

键盘类型图示:

  • UIKeyboardTypeDefault


    UIKeyboardTypeDefault

  • UIKeyboardTypeASCIICapable


    UIKeyboardTypeASCIICapable

  • UIKeyboardTypeNumbersAndPunctuation


    UIKeyboardTypeNumbersAndPunctuation

  • UIKeyboardTypeURL


    UIKeyboardTypeURL

  • UIKeyboardTypeNumberPad


    UIKeyboardTypeNumberPad

  • UIKeyboardTypePhonePad


    UIKeyboardTypePhonePad

  • UIKeyboardTypeNamePhonePad


    UIKeyboardTypeNamePhonePad

  • UIKeyboardTypeEmailAddress


    UIKeyboardTypeEmailAddress

  • UIKeyboardTypeDecimalPad


    UIKeyboardTypeDecimalPad

  • UIKeyboardTypeTwitter


    UIKeyboardTypeTwitter

  • UIKeyboardTypeWebSearch


    UIKeyboardTypeWebSearch

  • UIKeyboardTypeASCIICapableNumberPad(iOS 10.0开始引入)


    UIKeyboardTypeASCIICapableNumberPad(iOS 10.0开始引入)

收起键盘

收起键盘的两种方法:

  • 使用endEditing:方法;
  • 注销第一响应者resignFirstResponder

1. endEditing:
在触摸开始方法中,或者添加手势的响应方法中,添加endEditing:

// 触摸开始响应方法
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

    [self.view endEditing:YES];     // 结束视图(或子视图)内所有编辑,即收起键盘
}

2. resignFirstResponder
在按下键盘返回键的代理方法中(这样可以获取相应TextField对象),注销TextField对象第一响应者,将会收起键盘。

/**
 按下键盘返回键时
 应用举例:调用resignFirstResponder方法收回键盘

 @param textField UITextField对象
 @return 我发现返回YES或NO,效果都一样...
 */
- (BOOL)textFieldShouldReturn:(UITextField *)textField {

    [textField resignFirstResponder];      // 注销第一响应者,收起键盘

    return YES;
}

UITextFieldDelegate

设置TextField的代理后,我们可以跟踪TextField的一些编辑状态,进而处理一些事情。
第一步:遵循代理协议

<UITextFieldDelegate>

第二步:设置代理

textField.delegate = self;

第三步:实现代理方法

#pragma mark - UITextField代理方法

/**
 将要开始编辑

 @param textField UITextField对象
 @return YES:允许编辑; NO:禁止编辑
 */
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {

    return YES;
}


/**
 开始编辑,即成为第一响应者,此时光标出现

 @param textField UITextField对象
 */
- (void)textFieldDidBeginEditing:(UITextField *)textField {

    NSLog(@"开始编辑");
}



/**
 将要结束编辑
 应用场景:如果当前TextField有内容,则返回YES,允许收键盘或更换TextField;
         当前TextField没有输入内容,返回NO,此时不能收起键盘或者更换TextField

 @param textField UITextField对象
 @return YES:允许释放键盘(注销第一响应者); NO:不允许释放键盘(始终是第一响应者)
 */
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {

    // 过滤空格
    NSString *strWithoutSpace = [textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    if (strWithoutSpace.length == 0) {
        return NO;
    }
    return YES;
}


/**
 已经结束编辑
 (即使shouldEndEditing方法返回NO或者调用了endEditing:YES,该方法仍可能调用)
 官方注释:may be called if forced even if shouldEndEditing returns NO (e.g. view removed from window) or endEditing:YES called

 @param textField UITextField对象
 */
- (void)textFieldDidEndEditing:(UITextField *)textField {

    NSLog(@"已经结束编辑");
}


/**
 已经结束编辑(iOS 10.0开始引入)
 如果实现,将取代textFieldDidEndEditing:方法

 @param textField UITextField对象
 @param reason 结束原因(正常代理结束或者被迫取消)
 */
- (void)textFieldDidEndEditing:(UITextField *)textField reason:(UITextFieldDidEndEditingReason)reason NS_AVAILABLE_IOS(10_0) {

    NSLog(@"已经结束编辑(iOS 10.0开始引入)");
}


/**
 将要改变文字内容时
 应用场景:1.撤销上一次输入
         2.跟踪本TextField所做的最后一次修改
         3.防止文字被改变
         4.限制输入字符类型

 @param textField UITextField对象
 @param range 被修改内容的范围
 @param string 修改内容取代者
 @return YES:允许修改; NO:不允许修改
 */
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

    return YES;
}


/**
 当按下清除按钮时

 @param textField UITextField对象
 @return YES:允许清除; NO:不许清除
 */
- (BOOL)textFieldShouldClear:(UITextField *)textField {

    return YES;
}


/**
 按下键盘返回键时
 应用举例:调用resignFirstResponder方法收回键盘

 @param textField UITextField对象
 @return 我发现返回YES或NO,效果都一样...
 */
- (BOOL)textFieldShouldReturn:(UITextField *)textField {

    [textField resignFirstResponder];

    return YES;
}

限制UITextField输入字符类型及字符个数

1. 限制输入字符类型

在代理方法中作判断,符合返回YES,不符合返回NO。
例如匹配输入为纯数字:

/**
 将要改变文字内容时
 应用场景:1.撤销上一次输入
         2.跟踪本TextField所做的最后一次修改
         3.防止文字被改变
         4.限制输入字符类型

 @param textField UITextField对象
 @param range 被修改内容的范围
 @param string 修改内容取代者
 @return YES:允许修改; NO:不允许修改
 */
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

    // 匹配纯数字
    NSString *regex = @"[0-9]";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    return [pred evaluateWithObject:string];    // 匹配返回YES,否则返回NO
}

2. 限制输入字符个数

字符个数决定了字符串的长度。
在代理方法中很难实时地获得字符串长度,因此不好在代理方法里判断。好在苹果提供了监听UITextField的编辑发生改变的事件,可在该事件中作判断。
首先要添加事件:

[textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];

然后实现事件响应方法:

// 当编辑发生改变
- (void)textFieldDidChange:(UITextField *)textField {

    // 获取字符串长度
    NSUInteger strLength = 0;
    for (NSUInteger i=0; i<textField.text.length; i++) {
        unichar uc = [textField.text characterAtIndex: I];
        strLength += isascii(uc) ? 1:2;     // 汉字两个字节
    }

    // 如果字符串大于5,裁掉后尾
    if (strLength > 5) {
        textField.text = [textField.text substringToIndex:5];
    }
}

解决键盘遮挡UITextField问题

首先监听键盘显示/收回的系统通知

    /* ----- 解决键盘遮挡问题 ----- */
    // 监听系统要弹出键盘时,发出该通知
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillShow:)
                                                 name:UIKeyboardWillShowNotification
                                               object:nil];

    // 监听系统要回收键盘时,发出该通知
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillHide:)
                                                 name:UIKeyboardWillHideNotification
                                               object:nil];

实现通知响应方法

#pragma mark - 系统通知调用方法

// 当键盘将要显示时
- (void)keyboardWillShow:(NSNotification *)notification {

    // 获取键盘的frame
    CGRect keyboardRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];

    // 判断输入框是否被遮挡
    NSInteger distance = textField.frame.origin.y + textField.frame.size.height - keyboardRect.origin.y;
    if(distance>0) {
        // 把界面上移,动画时间0.25s,与键盘同步
        [UIView animateWithDuration:0.25 animations:^{
            self.view.frame = CGRectMake(0, -distance, self.view.frame.size.width, self.view.frame.size.height);
        }];
    }
}


// 当键盘将要回收时
- (void)keyboardWillHide:(NSNotification *)notification {

    // 背景view恢复原位
    self.view.frame = self.view.bounds;
}

对了,既然添加了通知,不要忘了在适当的时候移除哟~

- (void)dealloc {

    [[NSNotificationCenter defaultCenter] removeObserver:self];     // 移除通知
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值