• 限制 UITextField 输入长度


    限制 UITextField 输入长度

    标签(空格分隔): UITextField


      UITextField 是 iOS 中最经常使用的组件之中的一个。关于它也有各种各样的需求,这些需求是它本身没有提供对应的API的。限制输入框文本长度是常见的需求,UITextField 本身也并没有为此提供API。本文尝试给其加入这个功能。

    1、通过 delegate 来实现(不推荐)

      限制 UITextField 的输入字数,首先想到的是 UITextFieldDelegate,通过实现这个协议来实现需求:

    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
     replacementString:(NSString *)string; // 返回 NO 就不会改变文本

      OK。那咱们来试试看:

    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
      NSString *beString = [textField.text stringByReplacingCharactersInRange:range withString:string];
      if ([beString length] > 20) {
        textField.text = [beString substringToIndex:20];
        return NO;
      }
    
      return YES;
    }

      1. 先计算出在用户输入这段文字会产生的新文本:beString。


      2. 再推断beString长度是否符合长度限制(这里为20)。
      3. 假设符合则返回YES。否则返回NO。

      OK,这么做实现了咱们的需求,在各种输入法、中英文下都执行无误。

    这就完了?NO!
      我们来说说这样的解决文案的不足之处:
      1. 代码量太多。

    看看上面的样例,这还是仅仅是一个输入框,假设有2个、3个、N个。。

    。 (这得又一次考虑一下你们的需求了)
      2. 给每个要限制长度的输入框都得这么写,想想也是醉了(没错,偶曾经也是这么干的)。

    2、继承 UITextField来实现(不推荐)

      继承 UITextField ,覆写 setText: 方法应该是能够实现的(偶没做过)。但基于无数先辈们得出的经验:组合先于继承。

    在这里用继承也是有点小问题的:假设咱们子类名字为 NLUITextFieldTextLimit。那 NITextFieldnimbus 框架中的一个类) 对象也就无法享受到这一服务了。

    3、分类加入属性来实现(推荐)

      假设能用分类,加入一个属性来实现这个需求得多爽呀。在 UITextField 中定义一个属性就好了。

    咱们来研究一下 UITextField 看看有没有可能。

    @interface UITextField : UIControl
    ...

      UITextField 是继承自 UIControl 的,那它能够监听自身的事件咯。Good!

    我们仅仅要得知其输入文本变化后。再推断长度是否符合需求。看看咱们的代码:

    // .h file
    @interface UITextField (NLLimit)
    @property (assign, nonatomic) NSUInteger nl_maxLength;
    @end
    
    // .m file
    #import <objc/runtime.h>
    @implementation UITextField (NLLimit)
    static void *nlLimitMaxLengthKey = &nlLimitMaxLengthKey;
    - (void)setNl_maxLength:(NSUInteger)nl_maxLength {
      objc_setAssociatedObject(self, nlLimitMaxLengthKey, @(nl_maxLength), OBJC_ASSOCIATION_COPY);
    
      /**
       *  监控自身文本变化
       */
      if (nl_maxLength > 0) {
        [self addTarget:self action:@selector(_nl_valueChanged:) forControlEvents:UIControlEventAllEditingEvents];
      } else {
        [self removeTarget:self action:@selector(_nl_valueChanged:) forControlEvents:UIControlEventAllEditingEvents];
      }
    }
    
    - (NSUInteger)nl_maxLength {
      return [objc_getAssociatedObject(self, nlLimitMaxLengthKey) unsignedIntegerValue];
    }
    
    #pragma mark - private
    - (void)_nl_valueChanged:(UITextField *)textField {
      /**
       * 在文本变化后推断文本长度是否符合需求
       */
      if (self.nl_maxLength == 0) return;
      if ([textField.text length] <= self.nl_maxLength) return;
    
      NSString *subString = [textField.text substringToIndex:self.nl_maxLength];
      dispatch_async(dispatch_get_main_queue(), ^{
        textField.text = subString;
        [textField sendActionsForControlEvents:UIControlEventEditingChanged];
      });
    }
    @end

      代码在这里
      嗯,简单直接,就是它了!
      

    4、限制 UITextView 输入长度

      在 UITextField 中我们推荐的限制文本长度的方式是通过分类中加入属性来做到的,其本质是监控自身的输入文本变化。再推断长度是否符合需求。

    UITextView 是不是也能够这么做呢?

    @interface UITextView : UIScrollView

      可惜的是,正如上面所看到的。UITextViewUIScrollView 的子类。并不是如 UITextField 那般是 UIControl 的子类,也就是说 UITextView 无法像 UITextField 那样通过监控自身的来达到限制的目的了。
      只是好在我们在 UITextView 的说明文档中看到了几个通知:

    NSString * const UITextViewTextDidBeginEditingNotification;
    NSString * const UITextViewTextDidChangeNotification;
    NSString * const UITextViewTextDidEndEditingNotification;

      通过这几个通知也能够得知不论什么一个 UITextView 输入文本的变化了。

    咱们能够整个辅助类来做到这一点。

    代码就不贴出来了,你也能够自己试验一下。想看完整代码,在这里
      

  • 相关阅读:
    软阴影的实现(转帖)
    卡巴斯基:警惕IE拦截器恶意推广导航网站 狼人:
    安全问题拷问着电子支付第三方未来 狼人:
    微软警告:泄露的Office 2010预览版或含病毒 狼人:
    《越狱》完结 米帅迷应小心纹身网站挂马 狼人:
    赛门铁克和McAfee:目标锁定iPhone! 狼人:
    McAfee将与EMC合作推出在线PC备份服务 狼人:
    恶意软件分析师:面临社交网络威胁的用户已10亿 狼人:
    Mac OS X现漏洞 苹果称是Java导致恶意攻击 狼人:
    暴风影音声明:DNS服务器才是故障源头 狼人:
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5275833.html
Copyright © 2020-2023  润新知