美文网首页iOS程序员的业余沙龙
iOS开发: 输入框输入内容长度限制优化 - 完整输入最大限制的

iOS开发: 输入框输入内容长度限制优化 - 完整输入最大限制的

作者: 伯wen | 来源:发表于2017-07-06 11:26 被阅读131次
    • 目标效果: 在限制文本输入长度的时候, 输入汉字可以正常输入最长限度


      目标效果
    • 在iOS开发中, 经常有输入框输入内容长度限制的需求, 如果我们只判断输入框文本长度, 然后进行切割, 那么就会在输入汉字时无法正常输入全部长度的汉字, 如下图


      13.gif
    • 代码如下

    if (self.text.length > 10) {
        self.text = [self.text substringToIndex:10];
    }
    

    上述代码虽然也做到了对输入内容进行长度限制, 但是在输入中文时的体验并不是很好, 因为最后的几个字如果拼音较长就很难输入

    • 所以我们需要对限制长度的代码进行优化, 让用户在输入汉字时, 可以完整便捷的输入最大长度的汉字, 就如最上方目标效果一样
    • 优化代码如下:
    NSString *InputMethodType = [[UIApplication sharedApplication]textInputMode].primaryLanguage;
    
    // 如果当前输入法为汉语输入法
    if ([InputMethodType isEqualToString:@"zh-Hans"]) {
        
        // 获取标记部分
        UITextRange *selectedRange = [self markedTextRange];
        
        //获取标记部分, 此部分为用户未决定输入部分
        UITextPosition *position = [self positionFromPosition:selectedRange.start offset:0];
        
        // 当没有标记部分时截取字符串
        if (position == nil) {
            if (self.text.length > 10) {
                self.text = [self.text substringToIndex:10];
            }
        }
    }else {
        if (self.text.length > 10) {
            self.text = [self.text substringToIndex:10];
        }
    }
    
    • 下面是我写的分类代码, 可以在项目中直接使用
    • .h文件代码
    //
    //  UITextField+LTExtension.h
    //  LTTextField
    //
    //  Created by 冰凌天 on 2017/7/6.
    //  Copyright © 2017年 冰凌天. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    @interface UITextField (LTExtension)
    
    /** 最大输入长度 */
    @property (nonatomic, assign) NSInteger maxInputLenght;
    
    @end
    
    • .m文件代码
    //
    //  UITextField+LTExtension.m
    //  LTTextField
    //
    //  Created by 冰凌天 on 2017/7/6.
    //  Copyright © 2017年 冰凌天. All rights reserved.
    //
    
    #import "UITextField+LTExtension.h"
    #import <objc/runtime.h>
    
    static NSString *maxInputLenghtKey = @"maxInputLenghtKey";
    
    @interface UITextField ()
    
    /** 是否已经设置过最大值 */
    @property (nonatomic, assign) NSInteger isSetupMaxInputLenght;
    
    @end
    
    @implementation UITextField (LTExtension)
    
    #pragma mark - < 方法交换 >
    
    + (void)load
    {
        Method dealloc = class_getInstanceMethod(self, NSSelectorFromString(@"dealloc"));
        Method lt_dealloc = class_getInstanceMethod(self, @selector(lt_dealloc));
        method_exchangeImplementations(dealloc, lt_dealloc);
        
        Method initWithFrame = class_getInstanceMethod(self, NSSelectorFromString(@"initWithFrame:"));
        Method lt_initWithFrame = class_getInstanceMethod(self, @selector(lt_initWithFrame:));
        method_exchangeImplementations(initWithFrame, lt_initWithFrame);
        
        
        Method initWithCoder = class_getInstanceMethod(self, NSSelectorFromString(@"initWithCoder:"));
        Method lt_initWithCoder = class_getInstanceMethod(self, @selector(lt_initWithCoder:));
        method_exchangeImplementations(initWithCoder, lt_initWithCoder);
    }
    
    - (void)lt_dealloc
    {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
        [self lt_dealloc];
    }
    
    - (instancetype)lt_initWithFrame:(CGRect)frame
    {
        [self lt_initWithFrame:frame];
        
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(lt_category_maxInputLenght_textDidChangeNotification:) name:UITextFieldTextDidChangeNotification object:nil];
        
        return self;
    }
    
    - (instancetype)lt_initWithCoder:(NSCoder *)coder
    {
        [self lt_initWithCoder:coder];
        
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(lt_category_maxInputLenght_textDidChangeNotification:) name:UITextFieldTextDidChangeNotification object:nil];
        return self;
    }
    
    #pragma mark - < 属性绑定 >
    
    - (void)setMaxInputLenght:(NSInteger)maxInputLenght
    {
        objc_setAssociatedObject(self, (__bridge const void *)(maxInputLenghtKey), @(maxInputLenght), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (NSInteger)maxInputLenght
    {
        NSNumber *maxInputLenght = objc_getAssociatedObject(self, (__bridge const void *)(maxInputLenghtKey));
        return maxInputLenght.integerValue;
    }
    
    #pragma mark - < 输入框内容处理 >
    
    - (void)lt_category_maxInputLenght_textDidChangeNotification:(NSNotification *)notification
    {
        if (self.maxInputLenght <= 0) return;
        
        NSString *InputMethodType = [[UIApplication sharedApplication]textInputMode].primaryLanguage;
        
        // 如果当前输入法为汉语输入法
        if ([InputMethodType isEqualToString:@"zh-Hans"]) {
            
            // 获取标记部分
            UITextRange *selectedRange = [self markedTextRange];
            
            //获取标记部分, 此部分为用户未决定输入部分
            UITextPosition *position = [self positionFromPosition:selectedRange.start offset:0];
            
            // 当没有标记部分时截取字符串
            if (position == nil) {
                if (self.text.length > self.maxInputLenght) {
                    self.text = [self.text substringToIndex:self.maxInputLenght];
                }
            }
        }else {
            if (self.text.length > self.maxInputLenght) {
                self.text = [self.text substringToIndex:self.maxInputLenght];
            }
        }
    }
    
    @end
    
    Swift版本
    import UIKit
    
    class LTTextField: UITextField {
    
        var maxInputlength = 0
        
        override var text: String? {
            didSet {
                self.textDidChange()
            }
        }
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            
            NotificationCenter.default.addObserver(self, selector: #selector(textDidChange), name: NSNotification.Name.UITextFieldTextDidChange, object: nil)
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        @objc fileprivate func textDidChange() {
        
            if maxInputlength <= 0 {
                return
            }
            
            let inputMethodType : String = UIApplication.shared.textInputMode?.primaryLanguage ?? ""
            
            if inputMethodType == "zh-Hans" {
                if let selectedRange = markedTextRange {
                   let p = position(from: selectedRange.start, offset: 0)
                    if p == nil {
                        if (text?.characters.count ?? 0) > maxInputlength {
                            text = (text! as NSString).substring(to: maxInputlength)
                        }
                    }
                }else {
                    if (text?.characters.count ?? 0) > maxInputlength {
                        text = (text! as NSString).substring(to: maxInputlength)
                    }
                }
            }else {
                if (text?.characters.count ?? 0) > maxInputlength {
                    text = (text! as NSString).substring(to: maxInputlength)
                }
            }
        }
        
        deinit {
            NotificationCenter.default.removeObserver(self)
        }
    }
    
    • 最后: 上面的内容如果有错误或者可优化的地方请留言, 我会进行修改

    相关文章

      网友评论

        本文标题:iOS开发: 输入框输入内容长度限制优化 - 完整输入最大限制的

        本文链接:https://www.haomeiwen.com/subject/xpkhhxtx.html