iOS-仿京東6位密碼支付輸入框

開發(fā)需求中有時候我們需要用于安全支付的功能, 需要設(shè)置APP錢包的支付密碼, 頁面是仿照京東的6位輸入框的的做法, 效果如下圖:



看起來是有由6個UITextField組成, 其實(shí)并不是,這只是一個假象.

實(shí)現(xiàn)思路:

  1. 創(chuàng)建一個UITextField暇藏,僅僅一個而不是六個! 然后用5根豎線進(jìn)行分割蹂随,這樣我們看到的就是一個有6個等同輸入框的視圖.
  2. 創(chuàng)建黑點(diǎn)可以通過創(chuàng)建一個正方形的UIView够话,設(shè)置圓角為寬高的一半担汤,就是一個圓了壤巷,使其 frame 顯示在中間則黑點(diǎn)居中即可.
  3. 當(dāng)點(diǎn)擊輸入時候使用shouldChangeCharactersInRange 方法來用來輸入的 textfield 做處理, 是否成為第一響應(yīng)者,用來用戶輸入, 監(jiān)聽其值的改變.
  4. 當(dāng)密碼的長度達(dá)到需要的長度時,關(guān)閉第一響應(yīng)者. 這里可以使用 block 來傳遞 password 的值.
  5. 提供一個清除 password 的方法

現(xiàn)在核心代碼如下:

先抽出加密支付頁面 ZLSafetyPswView, 在.m中主要就是實(shí)現(xiàn)頁面的效果:

#define kDotSize CGSizeMake (10, 10) // 密碼點(diǎn)的大小
#define kDotCount 6  // 密碼個數(shù)
#define K_Field_Height self.frame.size.height  // 每一個輸入框的高度等于當(dāng)前view的高度

@interface ZLSafetyPswView () <UITextFieldDelegate>

// 密碼輸入文本框
@property (nonatomic, strong) UITextField *pswTextField;
// 用于存放加密黑色點(diǎn)
@property (nonatomic, strong) NSMutableArray *dotArr;

@end

創(chuàng)建分割線和黑點(diǎn).

#pragma mark - 懶加載

- (NSMutableArray *)dotArr {
    if (!_dotArr) {
        _dotArr = [NSMutableArray array];

    }
    return _dotArr;
}
- (instancetype)initWithFrame:(CGRect)frame {
    
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor whiteColor];
        
        [self setupWithPswTextField];
    }
    return self;
}

- (void)setupWithPswTextField {
    
    // 每個密碼輸入框的寬度
    CGFloat width = self.frame.size.width / kDotCount;
    
    // 生成分割線
    for (int i = 0; i < kDotCount - 1; i++) {
        UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMinX(self.pswTextField.frame) + (i + 1) * width, 0, 1, K_Field_Height)];
        lineView.backgroundColor = [UIColor grayColor];
        [self addSubview:lineView];
    }
    
    self.dotArr = [[NSMutableArray alloc] init];
    
    // 生成中間的黑點(diǎn)
    for (int i = 0; i < kDotCount; i++) {
        UIView *dotView = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMinX(self.pswTextField.frame) + (width - kDotCount) / 2 + i * width, CGRectGetMinY(self.pswTextField.frame) + (K_Field_Height - kDotSize.height) / 2, kDotSize.width, kDotSize.height)];
        dotView.backgroundColor = [UIColor blackColor];
        dotView.layer.cornerRadius = kDotSize.width / 2.0f;
        dotView.clipsToBounds = YES;
        dotView.hidden = YES; // 首先隱藏
        [self addSubview:dotView];
        
        // 把創(chuàng)建的黑色點(diǎn)加入到存放數(shù)組中
        [self.dotArr addObject:dotView];
    }
}

創(chuàng)建一個UITextField.切記輸入的文字顏色和輸入框光標(biāo)的顏色為透明!

#pragma mark - init

- (UITextField *)pswTextField {
    
    if (!_pswTextField) {
        _pswTextField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, K_Field_Height)];
        _pswTextField.backgroundColor = [UIColor clearColor];
        // 輸入的文字顏色為無色
        _pswTextField.textColor = [UIColor clearColor];
        // 輸入框光標(biāo)的顏色為無色
        _pswTextField.tintColor = [UIColor clearColor];
        _pswTextField.delegate = self;
        _pswTextField.autocapitalizationType = UITextAutocapitalizationTypeNone;
        _pswTextField.keyboardType = UIKeyboardTypeNumberPad;
        _pswTextField.layer.borderColor = [[UIColor grayColor] CGColor];
        _pswTextField.layer.borderWidth = 1;
        [_pswTextField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
        [self addSubview:_pswTextField];
    }
    return _pswTextField;
}

文本框內(nèi)容改變時,用來用戶輸入, 監(jiān)聽其值的改變.

#pragma mark - 文本框內(nèi)容改變

/**
 *  重置顯示的點(diǎn)
 */
- (void)textFieldDidChange:(UITextField *)textField {
    
    NSLog(@"目前輸入顯示----%@", textField.text);
    
    for (UIView *dotView in self.dotArr) {
        dotView.hidden = YES;
    }
    for (int i = 0; i < textField.text.length; i++) {
        ((UIView *)[self.dotArr objectAtIndex:i]).hidden = NO;
    }
    if (textField.text.length == kDotCount) { 
        NSLog(@"---輸入完畢---");
        
        [self.pswTextField resignFirstResponder];
    }
    
    // 獲取用戶輸入密碼
    !self.passwordDidChangeBlock ? : self.passwordDidChangeBlock(textField.text);
}

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    
    NSLog(@"輸入變化%@", string);
    if([string isEqualToString:@"\n"]) { // 按回車關(guān)閉鍵盤
        
        [textField resignFirstResponder];
        return NO;
    } else if(string.length == 0) { // 判斷是不是刪除鍵
        
        return YES;
    } else if(textField.text.length >= kDotCount) { // 輸入的字符個數(shù)大于6媳搪,則無法繼續(xù)輸入铭段,返回NO表示禁止輸入
        
        NSLog(@"輸入的字符個數(shù)大于6,后面禁止輸入則忽略輸入");
        return NO;
    } else {
        
        return YES;
    }
}

清除密碼時收起鍵盤并將文本輸入框值置為空.

#pragma mark - publick method

/**
 *  清除密碼
 */
- (void)clearUpPassword {
    [self.pswTextField resignFirstResponder];
    self.pswTextField.text = nil;
    [self textFieldDidChange:self.pswTextField];
}

接著在當(dāng)前所需控制器里,創(chuàng)建支付頁面并拿到用戶輸入密碼去做支付相關(guān)邏輯處理

// 加密支付頁面
    ZLSafetyPswView *pswView = [[ZLSafetyPswView alloc] initWithFrame:CGRectMake(50, 100, self.view.frame.size.width - 100, 45)];
    [self.view addSubview:pswView];
    self.pswView = pswView;
    pswView.passwordDidChangeBlock = ^(NSString *password) {
        NSLog(@"---用戶輸入密碼為: %@",password);
    };
    
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.backgroundColor = [UIColor orangeColor];
    button.frame = CGRectMake(100, 280, self.view.frame.size.width - 200, 50);
    [button addTarget:self action:@selector(clearPsw) forControlEvents:UIControlEventTouchUpInside];
    [button setTitle:@"清空密碼" forState:UIControlStateNormal];
    [self.view addSubview:button];

方便測試加上清空密碼按鈕

// 清空密碼
- (void)clearPsw {
    
    [self.pswView clearUpPassword];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self.view endEditing:YES];
}

我這里是做6位支付密碼的, 你同樣可以修改kDotCount密碼個數(shù)值,目前也有4位的.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末秦爆,一起剝皮案震驚了整個濱河市序愚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌等限,老刑警劉巖爸吮,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異望门,居然都是意外死亡形娇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門筹误,熙熙樓的掌柜王于貴愁眉苦臉地迎上來桐早,“玉大人,你說我怎么就攤上這事厨剪『逶停” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵祷膳,是天一觀的道長陶衅。 經(jīng)常有香客問我,道長直晨,這世上最難降的妖魔是什么搀军? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮勇皇,結(jié)果婚禮上奕巍,老公的妹妹穿的比我還像新娘。我一直安慰自己儒士,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布檩坚。 她就那樣靜靜地躺著着撩,像睡著了一般诅福。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拖叙,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天氓润,我揣著相機(jī)與錄音,去河邊找鬼薯鳍。 笑死咖气,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的挖滤。 我是一名探鬼主播崩溪,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼斩松!你這毒婦竟也來了伶唯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤惧盹,失蹤者是張志新(化名)和其女友劉穎乳幸,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體钧椰,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡粹断,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了嫡霞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瓶埋。...
    茶點(diǎn)故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖秒际,靈堂內(nèi)的尸體忽然破棺而出悬赏,到底是詐尸還是另有隱情,我是刑警寧澤娄徊,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布闽颇,位于F島的核電站,受9級特大地震影響寄锐,放射性物質(zhì)發(fā)生泄漏兵多。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一橄仆、第九天 我趴在偏房一處隱蔽的房頂上張望剩膘。 院中可真熱鬧,春花似錦盆顾、人聲如沸怠褐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奈懒。三九已至奠涌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間磷杏,已是汗流浹背溜畅。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留极祸,地道東北人慈格。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像遥金,于是被迫代替她去往敵國和親浴捆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容