• iOS 自定义安全键盘


    项目中需要使用自定义安全键盘,随机布局,键盘区域防截屏

    1. 自定义键盘,通过自定义UITextFieldinputViewinputAccessoryView实现

      • 首先确定键盘上所有的字符,数字、字母、符号、控制字符等;
        self.numbers = [@"0 1 2 3 4 5 6 7 8 9" componentsSeparatedByString:@" "];
        self.letters = [@"a b c d e f g h i j k l m n o p q r s backspace uppercase t u v w x y z return" componentsSeparatedByString:@" "];
        self.controls = [@"backspace uppercase return" componentsSeparatedByString:@" "];
        self.symbols = [@"~ ` ! @ # $ % ^ & * ( ) _ - + = { [ } ] | \\ : ; \" ' < , > backspace . ? / € £ ¥ space  return" componentsSeparatedByString:@" "];
        
      • 每个字符一个键位,点击字符设置输入框内容,点击控制字符修改键盘或者输入
        - (void)clickKey:(UIButton *)button {
            if ([self.controls containsObject:button.titleLabel.text] || button.titleLabel.text.length==0) {
                return;
            }
            NSString *inputKey = button.titleLabel.text;
            if ([button.titleLabel.text isEqualToString:@"space"]) {
                inputKey = @" ";
            }
            self.text = [NSString stringWithFormat:@"%@%@", self.text, inputKey];
            [self sendActionsForControlEvents:UIControlEventEditingChanged];//直接设置text不会触发controlevent事件,需要调用此方法
        }
        
      • 开始编辑时,对所有字符随机排序,并重新设置所有按键
        - (void)onBeginEditing {
            self.numbers = [self shuffleArray:self.numbers];
            self.letters = [self shuffleArray:self.letters];
        //    self.symbols = [self shuffleArray:self.symbols];
            [self changeKeyboardType:self.customAccessoryView.items[2] reset:YES];
        }
        
      • 点击右上角按钮,切换键盘
        //更改键盘类型
        - (void)changeKeyboardType:(UIBarButtonItem *)item reset:(BOOL)isReset {
            self.secureKeyboardType = !isReset && self.secureKeyboardType == WMYSecureKeyboardTypeCharacter ? WMYSecureKeyboardTypeSymbol : WMYSecureKeyboardTypeCharacter;
            BOOL isSymbol = self.secureKeyboardType == WMYSecureKeyboardTypeSymbol;
            NSArray *keys = isSymbol ? self.symbols : [self.numbers arrayByAddingObjectsFromArray:self.letters];
            for (int i = 0; i < self.customInputView.subviews.count; i ++) {
                NSString *key = (keys.count - 1 < i) || [keys[i] isEqualToString:@"backspace"] || [keys[i] isEqualToString:@"uppercase"] ? @"" : keys[i];
                UIButton *keyButton = self.customInputView.subviews[i];
                if (i == 30) {//回退键
                    [self setupUppercaseButton:keyButton isKey:isSymbol];
                    [keyButton setTitle:isSymbol?key:@"" forState:UIControlStateNormal|UIControlStateSelected];
                } else if (i == 36) {//空格键
                    [self setupSpaceButton:keyButton isBig:isSymbol];
                } else if (i == 37) {//隐藏按键
                    CGRect frame = keyButton.frame;
                    frame.size = isSymbol ? CGSizeMake(0, 0) : CGSizeMake(self.keyWidth, self.keyHeight);
                    keyButton.frame = frame;
                }
                [keyButton setTitle:key forState:UIControlStateNormal];
            }
            item.title = isSymbol ? @"数字/字母" : @"符号";
        }
        
    2. 洗牌算法,交换第i个和之后的某一个元素

        - (NSArray *)shuffleArray:(NSArray *)items {
            NSMutableArray *newItems = [NSMutableArray arrayWithArray:items];
            for (int i = 0; i < newItems.count; i++) {
                int randomIndex = arc4random()%(newItems.count - i) + i;
                id item = newItems[randomIndex];
                //过滤控制字符,防止控制字符交换位置引起混乱
                if ([self.controls containsObject:item] || [self.controls containsObject:newItems[i]]) continue;
                newItems[randomIndex] = newItems[i];
                newItems[i] = item;
            }
            return newItems;
        }
      
    3. 防截屏,通过UITextfield的安全输入实现,将需要防截屏的区域的父视图设置为下面的view,这里设置为_customInputView = [self getSecureView];

        //防截屏
        - (UIView *)getSecureView{
            UITextField *bgTextField = [[UITextField alloc] init];
            [bgTextField setSecureTextEntry:YES];
      
            UIView *bgView = bgTextField.subviews.firstObject;
            [bgView setUserInteractionEnabled:YES];
            return bgView;
        }
      
    4. 遇到的问题

      • 输入之后,不会触发UITextFieldcontrolEvents事件;每次设置输入之后,手动调用sendActionsForControlEvents方法,触发事件
      • 控制字符在字符数组中,随机排序后,导致显示混乱;通过过滤控制字符,不参与随机排序解决
      • 按照mac键盘输入所有字符,只有33个,少于字母和数字的36个;参考别的键盘,增加了€ £ ¥这三个符号
    5. 待完善内容

      • 还有单独数字输入的键盘,由于时间不够,暂时没写
      • 点击按键放大动画,因为时间问题,还没实现
    6. 参考链接

  • 相关阅读:
    使用集合组织相关数据
    深入类的方法
    深入C#数据类型
    上机练习1 更新会员积分
    魔兽争霸登录
    jQuery
    打卡系统
    [工具]kalilinux2016.2 更新后
    [技术分享]借用UAC完成的提权思路分享
    [技术分享]利用MSBuild制作msf免杀的后门
  • 原文地址:https://www.cnblogs.com/shenyuiOS/p/16088917.html
Copyright © 2020-2023  润新知