iOS 自定義安全鍵盤
阿新 • • 發佈:2022-04-01
專案中需要使用自定義安全鍵盤,隨機佈局,鍵盤區域防截圖
-
自定義鍵盤,通過自定義
UITextField
的inputView
和inputAccessoryView
實現- 首先確定鍵盤上所有的字元,數字、字母、符號、控制字元等;
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 ? @"數字/字母" : @"符號"; }
- 首先確定鍵盤上所有的字元,數字、字母、符號、控制字元等;
-
洗牌演算法,交換第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; }
-
防截圖,通過
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; }
-
遇到的問題
- 輸入之後,不會觸發
UITextField
的controlEvents
事件;每次設定輸入之後,手動呼叫sendActionsForControlEvents
方法,觸發事件 - 控制字元在字元陣列中,隨機排序後,導致顯示混亂;通過過濾控制字元,不參與隨機排序解決
- 按照mac鍵盤輸入所有字元,只有33個,少於字母和數字的36個;參考別的鍵盤,增加了
€ £ ¥
這三個符號
- 輸入之後,不會觸發
-
待完善內容
- 還有單獨數字輸入的鍵盤,由於時間不夠,暫時沒寫
- 點選按鍵放大動畫,因為時間問題,還沒實現
-
參考連結