UITextField 支持内容滚动、3位数字间空格分割、禁止选

2022-10-23  本文已影响0人  简繁之间_来去自然

1


textFieldScrollable.gif

2


textFieldSpace.gif

1 支持滚动

#import <UIKit/UIKit.h>

typedef NS_ENUM(NSUInteger, TextRangeChangedType) {
    TextRangeChangedTypeLeftAndBack,
    TextRangeChangedTypeLeftAndForward,
    TextRangeChangedTypeRightAndBack,
    TextRangeChangedTypeRightAndForward,
    TextRangeChangedTypeNone
};

NS_ASSUME_NONNULL_BEGIN

@interface ZTextFieldScrollable : UIView

@property (nonatomic, readonly, strong) UITextField *textField;

@end

typedef void(^SelectedTextRangeChangedBlock)(TextRangeChangedType changeType, CGFloat beforeTextWidth);

@interface InnerTextField : UITextField

- (nullable NSNumber *)getWidthFromDocumentBeginingToCursor;

- (nullable NSNumber *)getWidthFromDocumentBeginingToEnd;

@property (nonatomic, strong) SelectedTextRangeChangedBlock selectedTextRangeChangedBlock;

@end

NS_ASSUME_NONNULL_END


#import "ZTextFieldScrollable.h"

static const CGFloat kOneCutWidth = 41;
static const CGFloat kDefaultCutTimes = 3;

@interface ZTextFieldScrollable () <UIScrollViewDelegate, UIGestureRecognizerDelegate,UITextFieldDelegate>

@property (nonatomic, strong) UITextField *textField;

@property (nonatomic, strong) UIScrollView *scrollView;

@property (nonatomic, strong) UITapGestureRecognizer *tapGesture;

@property (nonatomic, strong) NSLayoutConstraint *textFiledWidthConstraint;

@end

@implementation ZTextFieldScrollable

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self configureSubviews];
    }
    return self;
}

- (void)configureSubviews {
    // scroll

    _scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
    _scrollView.contentSize = CGSizeMake(kOneCutWidth * kDefaultCutTimes, 0);
    _scrollView.showsVerticalScrollIndicator = NO;
    _scrollView.showsHorizontalScrollIndicator = NO;
    _scrollView.bounces = NO;
    _scrollView.delegate = self;
    _scrollView.backgroundColor = UIColor.greenColor;
    [self addSubview:_scrollView];
    _scrollView.translatesAutoresizingMaskIntoConstraints = NO;
    NSLayoutConstraint *scrollLeftCons = [NSLayoutConstraint constraintWithItem:_scrollView
                                                                      attribute:NSLayoutAttributeLeft
                                                                      relatedBy:NSLayoutRelationEqual
                                                                         toItem:self
                                                                      attribute:NSLayoutAttributeLeft
                                                                     multiplier:1
                                                                       constant:0];
    NSLayoutConstraint *scrollRightCons = [NSLayoutConstraint constraintWithItem:_scrollView
                                                                       attribute:NSLayoutAttributeRight
                                                                       relatedBy:NSLayoutRelationEqual
                                                                          toItem:self
                                                                       attribute:NSLayoutAttributeRight
                                                                      multiplier:1
                                                                        constant:0];
    NSLayoutConstraint *scrollTopCons = [NSLayoutConstraint constraintWithItem:_scrollView
                                                                     attribute:NSLayoutAttributeTop
                                                                     relatedBy:NSLayoutRelationEqual
                                                                        toItem:self
                                                                     attribute:NSLayoutAttributeTop
                                                                    multiplier:1
                                                                      constant:0];
    NSLayoutConstraint *scrollBottomCons = [NSLayoutConstraint constraintWithItem:_scrollView
                                                                        attribute:NSLayoutAttributeBottom
                                                                        relatedBy:NSLayoutRelationEqual
                                                                           toItem:self
                                                                        attribute:NSLayoutAttributeBottom
                                                                       multiplier:1
                                                                         constant:0];
    [self addConstraints:@[scrollLeftCons, scrollRightCons, scrollTopCons, scrollBottomCons]];

    // text field
    InnerTextField *newTextField = [[InnerTextField alloc] initWithFrame:CGRectZero];
//    newTextField.delegate = self;
    _textField = newTextField;
    [newTextField addTarget:self action:@selector(handleTextField) forControlEvents:UIControlEventEditingChanged];
    _tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
    _tapGesture.delegate = self;
    [newTextField addGestureRecognizer:_tapGesture];
    __weak typeof(self) ws = self;
    newTextField.selectedTextRangeChangedBlock = ^(TextRangeChangedType changeType, CGFloat beforeTextWidth) {
        __strong typeof(self) ss = ws;
        if (!ss) {
            return;
        }
        CGFloat div = 15;
        CGPoint originOffset = ss->_scrollView.contentOffset;
        if (beforeTextWidth < ss->_scrollView.contentOffset.x + div) {
            [UIView animateWithDuration:0.1 animations:^{
                ss->_scrollView.contentOffset = CGPointMake(MAX(beforeTextWidth - div, 0), originOffset.y);
            }];
        } else if (beforeTextWidth > originOffset.x + ss->_scrollView.bounds.size.width - div) {
            [UIView animateWithDuration:0.1 animations:^{
                ss->_scrollView.contentOffset = CGPointMake(beforeTextWidth - ss->_scrollView.bounds.size.width + div, originOffset.y);
            }];
        }
    };
    [_scrollView addSubview:newTextField];
    newTextField.translatesAutoresizingMaskIntoConstraints = NO;
    NSLayoutConstraint *textLeftCons = [NSLayoutConstraint constraintWithItem:newTextField
                                                                      attribute:NSLayoutAttributeLeft
                                                                      relatedBy:NSLayoutRelationEqual
                                                                         toItem:_scrollView
                                                                      attribute:NSLayoutAttributeLeft
                                                                     multiplier:1
                                                                       constant:0];
    NSLayoutConstraint *textTopCons = [NSLayoutConstraint constraintWithItem:newTextField
                                                                     attribute:NSLayoutAttributeTop
                                                                     relatedBy:NSLayoutRelationEqual
                                                                        toItem:self
                                                                     attribute:NSLayoutAttributeTop
                                                                    multiplier:1
                                                                      constant:0];
    NSLayoutConstraint *textBottomCons = [NSLayoutConstraint constraintWithItem:newTextField
                                                                        attribute:NSLayoutAttributeBottom
                                                                        relatedBy:NSLayoutRelationEqual
                                                                           toItem:self
                                                                        attribute:NSLayoutAttributeBottom
                                                                       multiplier:1
                                                                         constant:0];
    NSLayoutConstraint *textWidthCons = [NSLayoutConstraint constraintWithItem:newTextField
                                                                     attribute:NSLayoutAttributeWidth
                                                                     relatedBy:NSLayoutRelationEqual
                                                                        toItem:nil
                                                                     attribute:NSLayoutAttributeNotAnAttribute
                                                                    multiplier:1
                                                                      constant:kOneCutWidth * kDefaultCutTimes];
    [_scrollView addConstraint:textLeftCons];
    [self addConstraints:@[textTopCons, textBottomCons]];
    [newTextField addConstraint:textWidthCons];
    _textFiledWidthConstraint = textWidthCons;
}


- (void)handleTextField {
    InnerTextField *hookedTF = (InnerTextField *)_textField;
    if (![hookedTF isKindOfClass:InnerTextField.class]) {
        return;
    }
    NSNumber *width = [hookedTF getWidthFromDocumentBeginingToCursor];
    NSNumber *fullWidth = [hookedTF getWidthFromDocumentBeginingToEnd];
    if (!width || !fullWidth) {
        return;
    }
    CGFloat selfWidth = self.bounds.size.width;
    if (selfWidth == 0) {
        return;
    }
    //check max bounds
    CGSize originContentSize = _scrollView.contentSize;
    if (_scrollView.contentSize.width - fullWidth.doubleValue < kOneCutWidth) {
        if (_scrollView.contentSize.width <= fullWidth.doubleValue) {
            _scrollView.contentSize = CGSizeMake(fullWidth.doubleValue + kOneCutWidth, originContentSize.height);
        } else {
            _scrollView.contentSize = CGSizeMake(originContentSize.width + kOneCutWidth, originContentSize.height);
        }
        _textFiledWidthConstraint.constant = _scrollView.contentSize.width;
        [self layoutIfNeeded];
    }
    CGPoint originOffset = _scrollView.contentOffset;
    if (width.doubleValue >= selfWidth - 3) {
        if (width.doubleValue - originOffset.x >= 0 && width.doubleValue - originOffset.x < selfWidth) {
            return;
        }
        CGFloat diff = MAX(width.doubleValue - selfWidth + 3, 0);
        _scrollView.contentOffset = CGPointMake(diff, originOffset.y);
    } else {
        _scrollView.contentOffset = CGPointMake(0, originOffset.y);
    }
}

- (void)handleTap:(UITapGestureRecognizer *)gesture {
    CGPoint point = [gesture locationInView:_textField];
    UITextPosition *closestPosition = [_textField closestPositionToPoint:point];
    if (closestPosition) {
        _textField.selectedTextRange = [_textField textRangeFromPosition:closestPosition toPosition:closestPosition];
    }
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    InnerTextField *textField = (InnerTextField *)_textField;
    if (![textField isKindOfClass:InnerTextField.class]) {
        return;
    }
    NSNumber *currentTextWidth = [textField getWidthFromDocumentBeginingToEnd];
    if (!currentTextWidth) {
        return;
    }
    CGFloat selfWidth = self.frame.size.width;
    CGPoint originOffset = _scrollView.contentOffset;
    if (currentTextWidth.doubleValue < selfWidth) {
        _scrollView.contentOffset = CGPointMake(0, originOffset.y);
        return;
    }
    CGFloat maxOffsetX = currentTextWidth.doubleValue - selfWidth + 6;
    if (_scrollView.contentOffset.x > maxOffsetX) {
        _scrollView.contentOffset = CGPointMake(maxOffsetX, originOffset.y);
    }
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    if (gestureRecognizer == self.tapGesture) {
        return _textField.isFirstResponder;
    }
    return YES;
}

@end

@implementation InnerTextField

- (nullable NSNumber *)getWidthFromDocumentBeginingToCursor {
    UITextRange *selectedRange = self.selectedTextRange;
    if (selectedRange) {
        return [self getWidthFromDocumentBeginingToPosition:selectedRange.start];
    }
    return nil;
}

- (nullable NSNumber *)getWidthFromDocumentBeginingToEnd {
    NSString *str = self.text;
    if (str) {
        return @([self getWidthFromString:str]);
    }
    return nil;
}

- (TextRangeChangedType)changeTypeFromOldRange:(UITextRange *)oldRange toNewRange:(UITextRange *)newRange {
    NSInteger oldStart = [self offsetFromPosition:self.beginningOfDocument toPosition:oldRange.start];
    NSInteger oldEnd = [self offsetFromPosition:self.beginningOfDocument toPosition:oldRange.end];

    NSInteger newStart = [self offsetFromPosition:self.beginningOfDocument toPosition:newRange.start];
    NSInteger newEnd = [self offsetFromPosition:self.beginningOfDocument toPosition:newRange.end];

    if (oldStart == newStart && oldEnd != newEnd) {
        if (newEnd > oldEnd) {
            return TextRangeChangedTypeRightAndForward;
        } else if (newEnd < oldEnd) {
            return TextRangeChangedTypeRightAndBack;
        }
        return TextRangeChangedTypeNone;
    }
    if (oldStart != newStart && oldEnd == newEnd) {
        if (newStart < oldStart) {
            return TextRangeChangedTypeLeftAndBack;
        } else if (newStart > oldStart) {
            return TextRangeChangedTypeLeftAndForward;
        }
        return TextRangeChangedTypeNone;
    }
    if (oldStart == oldEnd && newStart == newEnd) {
        if (newStart > oldStart) {
            return TextRangeChangedTypeRightAndForward;
        } else if (newStart < oldStart) {
            return TextRangeChangedTypeLeftAndBack;
        }
    }
    return TextRangeChangedTypeNone;
}

- (CGFloat)getWidthFromString:(NSString *)text {
    UILabel *newLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    newLabel.text = text;
    UIFont *font = self.font ? : [UIFont systemFontOfSize:15];
    newLabel.font = font;
    [newLabel sizeToFit];
    return newLabel.bounds.size.width;
}

- (nullable NSNumber *)getWidthFromDocumentBeginingToPosition:(UITextPosition *)position {
    NSString *curText = self.text;
    if (!curText) {
        return nil;
    }
    NSInteger offset = [self offsetFromPosition:self.beginningOfDocument toPosition:position];
    if (offset <= curText.length && offset >= 0) {
        NSString *subStr = [curText substringToIndex:offset];
        CGFloat width = [self getWidthFromString:subStr];
        return @(width);
    } else {
        return nil;
    }
}

- (void)setText:(NSString *)text {
    [super setText:text];
    [self sendActionsForControlEvents:UIControlEventEditingChanged];
}

- (void)setSelectedTextRange:(UITextRange *)selectedTextRange {
    UITextRange *oldVal = self.selectedTextRange;
    UITextRange *newVal = selectedTextRange;
    if (oldVal && newVal) {
        TextRangeChangedType willChangeType = [self changeTypeFromOldRange:oldVal toNewRange:newVal];
        NSNumber *width = nil;
        if (willChangeType == TextRangeChangedTypeLeftAndBack || willChangeType == TextRangeChangedTypeLeftAndForward) {
            width = [self getWidthFromDocumentBeginingToPosition:newVal.start];
        } else if (willChangeType == TextRangeChangedTypeRightAndForward || willChangeType == TextRangeChangedTypeRightAndBack) {
            width = [self getWidthFromDocumentBeginingToPosition:newVal.end];
        }
        if (width && _selectedTextRangeChangedBlock) {
            _selectedTextRangeChangedBlock(willChangeType, width.floatValue);
        }
    }
    [super setSelectedTextRange:selectedTextRange];
}

@end

2.0 支持3位数字空格分割 - extension

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface UITextField (ZYFTextField)
/// 自动遵守代理, 若外界使用代理则可能会覆盖本方法, 外界使用代理时请使用 kDealStringWithSpace
- (void)kInitSpace;

/// 接收数据并展示为 空格拼接样式, 部分拦截场景会返回NO则需要shouldChangeCharactersInRange中return NO;
/// @param string 每次输入的字符
- (BOOL)kDealStringWithSpace:(NSString *)string range:(NSRange)range;

/// 获取当前真实数据, 不包含空格
- (NSString *)kGetRealString;
@end

NS_ASSUME_NONNULL_END

/** 使用场景1, 外界无需使用代理时
 *  [textField kInitSpace];
 *  获取真实文案 if Need
 *  [self.textField kGetRealString];
 */

/** 使用场景2, 外界需要使用代理时
 *
 *  textField.delegate = self;
 *
  - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
    if (![textField kDealStringWithSpace:string]) {
        return NO;
    }
        return YES;
    }
 *
 *  获取真实文案 if Need
 *  [self.textField kGetRealString];
 */

#import "UITextField+ZYFTextField.h"
#import <objc/runtime.h>

@interface UITextField (ZYFTextField)<UITextFieldDelegate>

@property (nonatomic, copy) NSString * kRealString;         // 当前所有展示数据
@property (nonatomic, copy) NSNumber * kHasSpace;           // 输入位数是否触发添加空格
@end

@implementation UITextField (ZYFTextField)

@dynamic kRealString;
@dynamic kHasSpace;

-(void)setKRealString:(NSString *)kRealString{
    objc_setAssociatedObject(self, @selector(kRealString), kRealString, OBJC_ASSOCIATION_COPY);
}

- (NSString *)kRealString{
    return objc_getAssociatedObject(self,_cmd);
}
-(void)setKHasSpace:(NSNumber *)kHasSpace{
    objc_setAssociatedObject(self, @selector(kHasSpace),  kHasSpace, OBJC_ASSOCIATION_COPY);
}

- (NSNumber *)kHasSpace{

    return objc_getAssociatedObject(self,_cmd);
}

- (void)kInitSpace{
    self.delegate = self;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
    NSLog(@"--==-s exten : %@---",string);
    if (![self kDealStringWithSpace:string range:range]) {
        return NO;
    }
        return YES;
}


- (NSString *)kGetRealString{
    if (self.kRealString) {
        return self.kRealString;
    }
    return @"";
}

- (BOOL)kDealStringWithSpace:(NSString *)string range:(NSRange)range{
    NSString * realStr = [self.text stringByReplacingCharactersInRange:range withString:string];

    if (!self.kRealString) {
        self.kRealString = @"";
    }

    /// 非数字 且 非删除 return false
    BOOL isDelete = [string isEqualToString:@""];

    self.kRealString = [realStr stringByReplacingOccurrencesOfString:@" " withString:@""];

    // 2 符合规则后 更新展示1
    [self updateShow:!isDelete range:range string:string];

    // 3 部分拦截场景
    if ([self kShouldReturn:!isDelete]) {
        return NO;
    }
    return YES;
}


/// 展示带有空格分割的文本
/// @param isAdd 是否是输入操作
- (void)updateShow:(BOOL)isAdd range:(NSRange)range string:(NSString *)string{
    NSInteger realCount = self.kRealString.length;
    if (realCount >= 6) {
        self.kHasSpace = @1;

        NSInteger type = 0;
        if (realCount % 3 == 0) {
            type = 3;
        }else if(realCount % 4 == 0) {
            type = 4;
        }
        if (type > 0) {
            NSInteger currentSpaces = [self.text componentsSeparatedByString:@" "].count - 1;
            self.text = [self kFilterWithType:type];

            NSInteger totalSpace = [self kGetTotalSpace:type] - 1;
            currentSpaces = MAX(currentSpaces, 0);
            totalSpace = MAX(totalSpace, 0);
            NSInteger dif = totalSpace - currentSpaces;
            if (isAdd) {
                dif ++;
            }
            NSRange newRange = NSMakeRange(range.location + dif  , 0);
            if (string.length > 1) {
                NSInteger length = self.text.length;
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    [self setSelectedRange:NSMakeRange(length, 0)];
                });
            }else{
                [self setSelectedRange:newRange];
            }
        }
    }else if (realCount >= 3){
        if (!isAdd) {
            if (realCount % 3 == 0 && [self.kHasSpace integerValue] == 1) {
                self.text = [self kFilterWithType:3];
            }
        }
    }else{
        if (!isAdd) {
            self.kHasSpace = @0;
        }
    }
}

- (NSInteger)kGetTotalSpace:(NSInteger)type{
    NSString * str = self.kRealString;
    NSInteger count = str.length;
    NSInteger total = 0;
    if (type == 3 || type == 4) {
        if (str.length % type == 0) {
            total = count / type;
        }
    }
    return total;
}

/// 传入位数 , 根据位数动态拼接
/// @param type 位数
- (NSString *)kFilterWithType:(NSInteger)type{
    NSString * str = self.kRealString;
    NSInteger count = str.length;
    NSMutableArray * mutArr = [NSMutableArray array];
    if (type == 3 || type == 4) {
        if (str.length % type == 0) {
            for (int i = 0;i < count / type ; i++) {
                NSString * subStr = [str substringWithRange:NSMakeRange(i * type, type)];
                [mutArr addObject:subStr];
            }
        }
    }
    return [[mutArr copy] componentsJoinedByString:@" "];
}

/// 是否拦截 textfield拼接新输入的数据
/// @param isAdd 是否是输入操作
- (BOOL)kShouldReturn:(BOOL)isAdd{
    NSInteger realCount = self.kRealString.length;
    if (isAdd) {
        if (realCount >= 6) {
            if (realCount % 3 == 0) {
                return YES;
            }else if(realCount % 4 == 0) {
                return YES;
            }
        }
    }else{
        if (realCount >= 6) {
            if (realCount % 3 == 0 || realCount % 4 == 0) {
                return YES;
            }
        }else if (realCount >= 3){
            // 正常输入 未达到6位时, 不需要拦截, 该参数在输入达到6位时置成YES, 在删除到3位以下时 置为NO
            if (realCount % 3 == 0 && [self.kHasSpace isEqual:@1]) {
                return YES;
            }
        }
    }
    return NO;
}
@end

2.1 支持3位数字空格分割 - UITextField

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface ZYFTextFieldSpace : UITextField
 
@end

NS_ASSUME_NONNULL_END

#import "ZYFTextFieldSpace.h"

@interface ZYFTextFieldSpace()<UITextFieldDelegate>

@property (nonatomic, copy) NSString * kRealString;         // 当前所有展示数据
@property (nonatomic, copy) NSNumber * kHasSpace;           // 输入位数是否触发添加空格
@end
@implementation ZYFTextFieldSpace

//@synthesize text = _text;
 
-(NSString *)text{
    if (self.kRealString) {
        return self.kRealString;
    }
    return @"";
}
 
- (instancetype)init{
    self = [super init];
    if (self) {
        [self baseConfiguration];
        [self setupViews];
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        [self baseConfiguration];
        [self setupViews];
    }
    return self;
}

- (void)baseConfiguration{
    self.delegate = self;
}

- (void)setupViews{
     
}
#pragma mark  - - - UITextFieldDelegate - - -  Start
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
    if (![self kDealStringWithSpace:string range:range]) {
        return NO;
    }
        return YES;
}
#pragma mark  - - - UITextFieldDelegate - - -  End


- (BOOL)kDealStringWithSpace:(NSString *)string range:(NSRange)range{
    NSString * realStr = [self.text stringByReplacingCharactersInRange:range withString:string];

    if (!self.kRealString) {
        self.kRealString = @"";
    }

    /// 非数字 且 非删除 return false
    BOOL isDelete = [string isEqualToString:@""];

    self.kRealString = [realStr stringByReplacingOccurrencesOfString:@" " withString:@""];

    // 2 符合规则后 更新展示1
    [self updateShow:!isDelete range:range string:string];

    // 3 部分拦截场景
    if ([self kShouldReturn:!isDelete]) {
        return NO;
    }
    return YES;
}

- (void)updateShow:(BOOL)isAdd range:(NSRange)range string:(NSString *)string{
    NSInteger realCount = self.kRealString.length;
    if (realCount >= 6) {
        self.kHasSpace = @1;

        NSInteger type = 0;
        if (realCount % 3 == 0) {
            type = 3;
        }else if(realCount % 4 == 0) {
            type = 4;
        }
        if (type > 0) {
            NSInteger currentSpaces = [self.text componentsSeparatedByString:@" "].count - 1;
            self.text = [self kFilterWithType:type];

            NSInteger totalSpace = [self kGetTotalSpace:type] - 1;
            currentSpaces = MAX(currentSpaces, 0);
            totalSpace = MAX(totalSpace, 0);
            NSInteger dif = totalSpace - currentSpaces;
            if (isAdd) {
                dif ++;
            }
            NSRange newRange = NSMakeRange(range.location + dif  , 0);
            if (string.length > 1) {
                NSInteger length = self.text.length;
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    [self setSelectedRange:NSMakeRange(length, 0)];
                });
            }else{
                [self setSelectedRange:newRange];
            }
        }
    }else if (realCount >= 3){
        if (!isAdd) {
            if (realCount % 3 == 0 && [self.kHasSpace integerValue] == 1) {
                self.text = [self kFilterWithType:3];
            }
        }
    }else{
        if (!isAdd) {
            self.kHasSpace = @0;
        }
    }
}
 

- (NSInteger)kGetTotalSpace:(NSInteger)type{
    NSString * str = self.kRealString;
    NSInteger count = str.length;
    NSInteger total = 0;
    if (type == 3 || type == 4) {
        if (str.length % type == 0) {
            total = count / type;
        }
    }
    return total;
}
/// 传入位数 , 根据位数动态拼接
/// @param type 位数
- (NSString *)kFilterWithType:(NSInteger)type{
    NSString * str = self.kRealString;
    NSInteger count = str.length;
    NSMutableArray * mutArr = [NSMutableArray array];
    if (type == 3 || type == 4) {
        if (str.length % type == 0) {
            for (int i = 0;i < count / type ; i++) {
                NSString * subStr = [str substringWithRange:NSMakeRange(i * type, type)];
                [mutArr addObject:subStr];
            }
        }
    }
    return [[mutArr copy] componentsJoinedByString:@" "];
}
/// 是否拦截 textfield拼接新输入的数据
/// @param isAdd 是否是输入操作
- (BOOL)kShouldReturn:(BOOL)isAdd{
    NSInteger realCount = self.kRealString.length;
    if (isAdd) {
        if (realCount >= 6) {
            if (realCount % 3 == 0) {
                return YES;
            }else if(realCount % 4 == 0) {
                return YES;
            }
        }
    }else{
        if (realCount >= 6) {
            if (realCount % 3 == 0 || realCount % 4 == 0) {
                return YES;
            }
        }else if (realCount >= 3){
            // 正常输入 未达到6位时, 不需要拦截, 该参数在输入达到6位时置成YES, 在删除到3位以下时 置为NO
            if (realCount % 3 == 0 && [self.kHasSpace isEqual:@1]) {
                return YES;
            }
        }
    }
    return NO;
}

@end

3 禁止选中

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface ZYFTextField : UITextField
@property (nonatomic, assign) BOOL isBanSel;
@property (nonatomic, assign) BOOL isBanPerformAction;     
@end

NS_ASSUME_NONNULL_END

#import "ZYFTextField.h"

@implementation ZYFTextField

//@synthesize text = _text;
//
//
//-(NSString *)text{
//    return _text;
//}

/// 支持 系统item
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender{
    if (_isBanPerformAction) {
        return NO;
    }
//    if (action == @selector(paste:))//禁止粘贴
//        return NO;
//    if (action == @selector(select:))// 禁止选择
//        return NO;
//    if (action == @selector(selectAll:))// 禁止全选
//        return NO;

    return [super canPerformAction:action withSender:sender];
}

/// 选中范围
-(NSArray<UITextSelectionRect *> *)selectionRectsForRange:(UITextRange *)range{
    NSArray * arr = [super selectionRectsForRange:range];
    if (_isBanSel) {
        return @[];
    }
    return arr;
}

/// 光标位置
-(CGRect)caretRectForPosition:(UITextPosition *)position{
    if (_isBanSel) {
        return CGRectMake(-10, -10, 0, 0);
    }
    return [super caretRectForPosition:position];
}


@end

上一篇下一篇

猜你喜欢

热点阅读