iOS 验证码输入一种实现思路

如图所示,现在很多App采用了类似下划线、方块等方式的验证码输入,直观美观!对于这种效果的实现方式,大概有以下几种方式:

1.多个UITextField组成

这种方式好处是有光标闪烁、但是在处理删除和动画效果时,就会显得有点笨拙,OFO应该是这样实现的,要严格处理好每个UITextFieldFirstResponder

2.一个UITextField组成,使用富文本

这个方式是可行的, 使用富文本设置每个字符的间距,允许编辑富文本,有光标闪烁,缺点应该也是不好处理动画效果。

3.使用UIView绘制

这个是我在GitHub上看到的一个半成品Demo,利用一个UIView,使用Quartz 2DUIBezierPath进行绘制文本和下划线,并处理输入事件和键盘事件,其实整体下来代码也不多,300行以内,但是需要较好的iOS绘制功底。

4.一个UITextField和多个UILabel

这个是我接下来介绍的思路,这个思路的缺点应该是没有光标闪烁,其实也能伪实现,看是否必须要有这个需要了。这个思路比较简单,方便加入动画,纯粹下来就100多行,接下来看结构和代码:

新建一个UIView,初始化方法

- (instancetype)initWithCount:(NSInteger)count margin:(CGFloat)margin
{
    if (self = [super init]) {
        self.itemCount = count; // itemCount是验证码的个数,比如6个
        self.itemMargin = margin; // itemMargin是每个Label之间的间距
        [self configTextField];
    }
    return self;
}

添加内部子控件(演示)

- (void)configTextField
{
    UITextField *textField = [[UITextField alloc] init];
    textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
    textField.keyboardType = UIKeyboardTypeNumberPad;
    [textField addTarget:self action:@selector(tfEditingChanged:) forControlEvents:(UIControlEventEditingChanged)];

    // 小技巧:这个属性为YES,可以强制使用系统的数字键盘,缺点是重新输入时,会清空之前的内容
    // clearsOnBeginEditing 属性并不适用于 secureTextEntry = YES 时
    // textField.secureTextEntry = YES;

    [self addSubview:textField];
    self.textField = textField;

    // 小技巧:通过textField上层覆盖一个maskView,可以去掉textField的长按事件
    UIButton *maskView = [UIButton new];
    maskView.backgroundColor = [UIColor whiteColor];
    [maskView addTarget:self action:@selector(clickMaskView) forControlEvents:(UIControlEventTouchUpInside)];
    [self addSubview:maskView];
    self.maskView = maskView;

    for (NSInteger i = 0; i < self.itemCount; i++)
    {
        UILabel *label = [UILabel new];
        [self addSubview:label];
        [self.labels addObject:label];
    }

    for (NSInteger i = 0; i < self.itemCount; i++)
    {
        UIView *line = [UIView new];
        [self.lines addObject:line];
    }
}

这里可能对maskView有点费解,maskView主要是为了挡住下面的UITextField,使用类UIButton是为了挡住事件,因为如果使用类UIView,会将事件传递到self,会将事件传递到self,进而影响到外面隐藏键盘的代码,你可以试试就知道了。

主要处理业务逻辑的代码
#pragma mark - 编辑改变
- (void)tfEditingChanged:(UITextField *)textField
{
    if (textField.text.length > self.itemCount) {
        textField.text = [textField.text substringWithRange:NSMakeRange(0, self.itemCount)];
    }

    for (int i = 0; i < self.itemCount; i++)
    {
        UILabel *label = [self.labels objectAtIndex:i];

        if (i < textField.text.length) {
            label.text = [textField.text substringWithRange:NSMakeRange(i, 1)];
        } else {
            label.text = nil;
        }
    }

    // 输入完毕后,自动隐藏键盘
    if (textField.text.length >= self.itemCount) {
        [textField resignFirstResponder];
    }
}

这里没有使用UITextFielddelegate,使用UIControlEventEditingChanged足以,但是如果你的需求能输入英文等其他字符,就需要实现delegate去限制。

至此,验证码输入的核心代码就没有了,是不是感觉这么少!!在此基础上,我用Demo实现了3个基本效果,如图所示:

Github代码地址:点我

小技巧Tip

当你不想让别人使用某个方法时,除了私有方法办法之外,还可以这么做:

- (instancetype)init UNAVAILABLE_ATTRIBUTE;
+ (instancetype)new UNAVAILABLE_ATTRIBUTE;

有问题反馈

如果大家在使用过程中遇到其他问题,可以留言,我们共同解决。

作者:苦笑男神

链接:https://www.jianshu.com/p/23f7be3677be

iOS中的内嵌汇编

写一篇在iOS上使用汇编的文章的想法在脑袋里面停留了很久了,但是迟迟没有动手。虽然早前在做启动耗时优化的工作中,也做过通过拦截objc_msgSend并插入汇编指令来统计方法调用耗时的工作,但也只仅此而已。刚好最近的时间项目在做安全加固,需要写更多的汇编来提高安全性(文章内汇编使用指令集为ARM64),也就有了本文

发布于:2月以前  |  159次阅读  |  详细内容 »

不会吧,这也行?iOS后台锁屏监听摇一摇

一般情况下,出于省电、权限、合理性等因素考虑,给人的感觉是很多奇怪的需求安卓可以实现,但是iOS就无法实现!今天要介绍的需求也有这种感觉,就是“当 APP 处于后台或锁屏状态时,依旧可以监听到摇一摇,进而触发某些功能,比如:语音播报”。

发布于:2月以前  |  280次阅读  |  详细内容 »

iOS 稳定性:App 被终止的原因

本次 session 主要内容如下: 介绍了后台应用终止的常见原因,并提供了一些优化建议 介绍了 MetricsKit 提供的在代码中获取诊断和性能数据的方法 介绍了 Xcode Metrics Ogranizer 提供的关于线上用户性能数据的可视化报告

发布于:2月以前  |  384次阅读  |  详细内容 »

Vue中Axios的封装和API接口的管理

在vue项目中,和后台交互获取数据这块,我们通常使用的是axios库,它是基于promise的http库,可运行在浏览器端和node.js中。他有很多优秀的特性,例如拦截请求和响应、取消请求、转换json、客户端防御XSRF等。所以我们的尤大大也是果断放弃了对其官方库vue-resource的维护,直接推荐我们使用axios库。如果还对axios不了解的,可以移步axios文档。

发布于:2月以前  |  275次阅读  |  详细内容 »

iOS 持续集成:更完备的 App Store Connect API

时隔两年 App Store Connect API 有了更新,WWDC 2018 推出了 App Store Connect API ,用于自动化一些 App Store Connect 后台操作。这次更新包含了 app 元数据相关的API,补上了原来缺失的重要一环, 使得几乎可以通过 App Store Connect API 完成 App Store Connect 上的所有操作。今后开发、证书配置、用户管理、测试、发布全流程都可以通过 API 完成。

发布于:2月以前  |  330次阅读  |  详细内容 »

iOS 性能优化:优化 App 启动速度

苹果是一家特别注重用户体验的公司,过去几年一直在优化 App 的启动时间,特别是去年的 WWDC 2019 keynote[1] 上提到,在过去一年苹果开发团队对启动时间提升了 200%

发布于:2月以前  |  295次阅读  |  详细内容 »

让你的应用远离越狱:iOS 14 App Attest 防护功能

当越狱在 iOS 设备第一次流行起来时,iOS 开发人员会尝试各种方法来保护自己的应用程序,以让应用免受盗版等不确定因素的困扰。有许多方法可以做到这一点,包括检查 Cydia 是否存在、检测应用程序是否可读取自身沙箱之外的文件、在检测到调试器时让应用程序崩溃等等。

发布于:3月以前  |  324次阅读  |  详细内容 »

探秘 iOS 14 的 WidgetKit

Widget Extension 提供了 small, medium, large 三个尺寸,不同尺寸可以展示不同的数据、不同的界面,开发者也可以锁定自己APP的 Widget 只有某类尺寸,相同的widget也能重复添加。作为添加在主屏幕上的控件,苹果用了 “At a glance” 来形容 widget ,所以 widget extension 是无法交互的,它能做的只有展示一些信息与点击两个作用,点击后就会引导至app,同时为了性能与耗电量的考虑,Widget extension 也不能展示视频和动态图像。

发布于:3月以前  |  351次阅读  |  详细内容 »

iOS14 Widget 万字指北,先人一步获得顶级流量

2020 年 6 月 22 日,苹果召开了第一次线上的开发者大会 - WWDC20。这次发布会上宣布了ARM架构Mac芯片(拳打Intel)、iOS 14 ATT(脚踢Facebook),可谓是一次载入史册(我是爸爸)的发布会了,当然还发布了被称为下一个顶级流量入口的Widget。踩着八月的尾巴,本次我们就来探究一下Widget。本文会从Widget初窥和Widget开发两个维度和章节来探究一下Widget, 其中初窥章节会带您简单的了解一下Widget,适合应用决策者阅读; 开发章节会带着您一步一步的完成设计开发Widget,适合程序员阅读。

发布于:3月以前  |  487次阅读  |  详细内容 »

OCRunner:完全体的iOS热修复方案

为了能够实现一篇文章的思路:Objective-C源码 -> 二进制补丁文件 ->热更新(具体是哪篇我忘了)。当时刚好开始了oc2mango翻译器的漫漫长路(顺带为了学习编译原理,嘻嘻),等基本完成以后,就开始肝OCRunner:完全兼容struct,enum,系统C函数调用,魔改libffi,生成补丁文件等,尽可能兼容Objective-C,为了做一个直接运行OC的快乐人。

发布于:3月以前  |  423次阅读  |  详细内容 »

iOS APP图标版本化

在我们的项目开发过程中,需要频繁打包给测试人员去测试,有时候我们都不知道测试机上安装的版本是否是最新的,这样会造成很多不必要的麻烦和成本。因此我们需要将buildNumber以水印的方式打在APPIcon上,可以很直观的知道当前是哪一个版本。

发布于:3月以前  |  342次阅读  |  详细内容 »

最多阅读

快速配置 Sign In with Apple 1年以前  |  3752次阅读
开篇 关于iOS越狱开发 1年以前  |  2540次阅读
APP适配iOS11 1年以前  |  2496次阅读
给数组NSMutableArray排序 1年以前  |  2470次阅读
使用 GPUImage 实现一个简单相机 1年以前  |  2468次阅读
在越狱的iPhone设置上使用lldb调试 1年以前  |  2422次阅读
App Store 审核指南[2017年最新版本] 1年以前  |  2314次阅读
UITableViewCell高亮效果实现 1年以前  |  2294次阅读
所有iPhone设备尺寸汇总 1年以前  |  2241次阅读
使用ssh访问越狱iPhone的两种方式 1年以前  |  2164次阅读
关于Xcode不能打印崩溃日志 1年以前  |  2092次阅读
使用ssh 访问越狱iPhone的两种方式 1年以前  |  1998次阅读
UIDevice的简单使用 1年以前  |  1790次阅读
为对象添加一个释放时触发的block 1年以前  |  1762次阅读
使用最高权限操作iPhone手机 1年以前  |  1734次阅读