1、UITextField 限制输入小数,只能输入小数点后面有两位的代理方法:
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSMutableString * futureString = [NSMutableString stringWithString:textField.text];
[futureString insertString:string atIndex:range.location];
NSInteger flag=0;
const NSInteger limited = 2;
int dian = 0;
for (int i = futureString.length-1; i>=0; i--) {
if ([futureString characterAtIndex:i] == '.') {
dian++;
if (dian > 1) {
return NO;
}else{
if (flag > limited) {
return NO;
}
// break;
}
}
flag++;
}
return YES;
}
2、限制输入字符长度的方法
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (string.length == 0) {
if (textField.text.length == 1) {// 删掉了最后一位
return YES;
}else{//删掉了其中一位
return YES;
}
}else{
NSMutableString * futureString = [NSMutableString stringWithString:textField.text];
[futureString insertString:string atIndex:range.location];
if (futureString.length > 11) {
return NO;
}else{
return YES;
}
}
}
上面的写法对纯字符(英文和数字等)有效,但对中文无效。
这个代理方法触发的时机是每当在键盘上敲击了一个字符,导致了输入框中的蓝色高亮文本发生改变。string参数即为敲击的字符,也即为对高亮文本来说所发生的变化。乍看好像没什么问题:当输入的字符长度超过最大限制长度时,就从toBeString截取最大限制长度的子串。
但对于中文输入来说是存在问题的:输入框中高亮的文本并非最终显示在输入框的汉字,通过统计高亮文本的长度来限制输入汉字长度这明显是有问题的。这造成的结果是:当我想输入“喜剧之王”时,便最多只能输入"xijuz",因为这个长度统计的是高亮文本的长度,它此时已达到最大长度限制了,但实际上汉字还未超过最大限制长度,导致无法继续输入汉字,甚至一个汉字也输入不了。
怎么改善?
上面的问题在于对中文输入长度的统计方式不对,不能以高亮文本长度统计,应该以确确实实已选取,并已然显示在输入框的汉字统计。限制汉字的选取,但不限制高亮文本的变化。
但问题是,上面这个代理方法触发时机是高亮文本发生变动时,而在输入法选取汉字的动作并不会触发其执行。如此我们无法得知当前输入框已选的汉字们。
这就需要用到一个重要的通知了:UITextFieldTextDidChangeNotification
,注册该通知后不仅高亮文本发生变动时触发,选取汉字时也会触发。
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(textFeildEditChanged:) name:@"UITextFieldTextDidChangeNotification"
object:_textfield];
那我们来梳理一下限制控制的逻辑:
1.当输入纯字符时,只需比较toBeString的长度和最大限制长度,超出就截取toBeString的子串就行;
2.当输入汉字时,对高亮文本不做限制;对已然显示在输入框的汉字进行字数统计和限制,若超出最大限制长度就截取子串。
以上用代码实现就是:
- (void)textFeildEditChanged:(NSNotification *)notifition
{
// UITextField *tf = (UITextField *)notifition.object;
NSString *toBeString = _textfield.text;
NSString *lang = _textfield.textInputMode.primaryLanguage; // 键盘输入模式
if ([lang isEqualToString:@"zh-Hans"]) // 如果输入中文
{
UITextRange *selectedRange = [_textfield markedTextRange];
//获取高亮部分
UITextPosition *position = [_textfield positionFromPosition:selectedRange.start offset:0];
// 没有高亮选择的字,则对已输入的汉字进行字数统计和限制
if (!position)
{
if (toBeString.length > 5) {
_textfield.text = [toBeString substringToIndex:5];
}
}
// 对高亮文本不做限制,因为它不是最终显示在输入框的文本。
else
{
}
}
// 中文输入法以外的直接对其统计限制即可,不考虑其他语种情况
else
{
if (toBeString.length > 5) {
_textfield.text = [toBeString substringToIndex:5];
}
}
}
3、上面方法,如果是计算字节长度,把length方法改为一下在NSString中扩展的方法:
/**
* 计算字节数
*/
- (int)getByteCount//判断中英混合的的字符串长度
{
int strlength = 0;
char* p = (char*)[self cStringUsingEncoding:NSUnicodeStringEncoding];
for (int i=0 ; i<[self lengthOfBytesUsingEncoding:NSUnicodeStringEncoding] ;i++) {
if (*p) {
p++;
strlength++;
}
else {
p++;
}
}
return strlength;
}
4、自定义placeholder:
textfield设置placeholder只需这样:_textfield.placeholder = @"请输入姓名,限制5个字";
但有时产品设计得需要个性化一点,可能需要对placeholder的字体、颜色等进行自定制。比如:
NSDictionary *attriDict = @{NSFontAttributeName:[UIFont systemFontOfSize:11],
NSForegroundColorAttributeName:[UIColor blackColor]};
_textfield.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"请输入姓名,限制5个字"
attributes:attriDict];
我看到网上也有人说可以通过KVC给私有属性赋值的方式修改,但是我试过一次是无效的,也不知为什么。下来再研究研究。
遇到的问题:
当placeholder字体大小发生变化后,placeholder的文本可能不再垂直居中显示了!
解决方案:
子类化UITextField,重写placeholderRectForBounds:
方法,对placeholder的偏移量进行调整。
#import "YWTextField.h"
@implementation YWTextField
//控制placeHolder的位置,左右缩20
-(CGRect)placeholderRectForBounds:(CGRect)bounds
{
CGRect inset = CGRectMake(2, 6, bounds.size.width -10, bounds.size.height);
return inset;
}
@end
部分摘抄至文章:http://www.jianshu.com/p/d127225aece9#