iOS使用UIKeyInput自定义密码输入框的方法示例

前言

开发中很多地方都会遇到密码输入,这时候往往需要根据UI设计自定义。这里遵守UIKeyInput,实现协议中的方法,让自定义View可以进行文字输入;再通过func draw(_ rect: CGRect)绘制现自定义UI;使用配置类来统一接口;使用代理来管理各种输入相关的事件。文章末尾有提供OC和Swift双语的CLDemo下载,这里讲解就使用Swift。

1.遵守UIKeyInput协议,实现文字输入

遵守UIKeyInput协议,实现协议中- (BOOL)hasText - (void)insertText:(NSString *)text- (void)deleteBackward这三个方法。

这里方便阅读,单独抽离成为一个extension。

extension CLPasswordInputView: UIKeyInput {
 var hasText: Bool {
  return text.length > 0
 }

 func insertText(_ text: String) {
  if self.text.length < config.passwordNum {
   let cs = NSCharacterSet.init(charactersIn: "0123456789").inverted
   let string = text.components(separatedBy: cs).joined(separator: "")
   let basicTest = text == string
   if basicTest {
    self.text.append(text)
    delegate?.passwordInputViewDidChange(passwordInputView: self)
    if self.text.length == config.passwordNum {
     delegate?.passwordInputViewCompleteInput(passwordInputView: self)
    }
    setNeedsDisplay()
   }
  }
 }

 func deleteBackward() {
  if text.length > 0 {
   text.deleteCharacters(in: NSRange(location: text.length - 1, length: 1))
   delegate?.passwordInputViewDidChange(passwordInputView: self)
  }
  delegate?.passwordInputViewDidDeleteBackward(passwordInputView: self)
  setNeedsDisplay()
 }
}

2.重写override func draw(_ rect: CGRect),绘制自定义UI

根据配置信息,以及当前文字输入,绘制自定义UI,这里讲绘制代码和一些基本代码写在一起,单独抽离成extension。

extension CLPasswordInputView {
 override func becomeFirstResponder() -> Bool {
  if !isShow {
   delegate?.passwordInputViewBeginInput(passwordInputView: self)
  }
  isShow = true;
  return super.becomeFirstResponder()
 }
 override func resignFirstResponder() -> Bool {
  if isShow {
   delegate?.passwordInputViewEndInput(passwordInputView: self)
  }
  isShow = false
  return super.resignFirstResponder()
 }
 var keyboardType: UIKeyboardType {
  get {
   return .numberPad
  }
  set {

  }
 }
 override var canBecomeFirstResponder: Bool {
  return true
 }
 override var canResignFirstResponder: Bool {
  return true
 }
 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
  super.touchesBegan(touches, with: event)
  if !isFirstResponder {
   _ = becomeFirstResponder()
  }
 }
 func updateWithConfig(config: ((CLPasswordInputViewConfigure) -> Void)?) -> Void {
  config?(self.config)
  backgroundColor = self.config.backgroundColor
  setNeedsDisplay()
 }
 override func layoutSubviews() {
  super.layoutSubviews()
  setNeedsDisplay()
 }
 override func draw(_ rect: CGRect) {
  let height = rect.size.height
  let width = rect.size.width
  let squareWidth = min(max(min(height, config.squareWidth), config.pointRadius * 4), height)
  let pointRadius = min(config.pointRadius, squareWidth * 0.5) * 0.8
  let middleSpace = CGFloat(width - CGFloat(config.passwordNum) * squareWidth) / CGFloat(CGFloat(config.passwordNum - 1) + config.spaceMultiple * 2)
  let leftSpace = middleSpace * config.spaceMultiple
  let y = (height - squareWidth) * 0.5

  let context = UIGraphicsGetCurrentContext()

  for i in 0 ..< config.passwordNum {
   context?.addRect(CGRect(x: leftSpace + CGFloat(i) * squareWidth + CGFloat(i) * middleSpace, y: y, width: squareWidth, height: squareWidth))
   context?.setLineWidth(1)
   context?.setStrokeColor(config.rectColor.cgColor)
   context?.setFillColor(config.rectBackgroundColor.cgColor)
  }
  context?.drawPath(using: .fillStroke)
  context?.setFillColor(config.pointColor.cgColor)

  for i in 0 ..< text.length {
   context?.addArc(center: CGPoint(x: leftSpace + CGFloat(i + 1) * squareWidth + CGFloat(i) * middleSpace - squareWidth * 0.5, y: y + squareWidth * 0.5), radius: pointRadius, startAngle: 0, endAngle: .pi * 2, clockwise: true)
   context?.drawPath(using: .fill)
  }
 }
}

3.使用配置类,来统一接口,生成基本配置信息

自定义UI过程中,对于颜色,间隙,原点大小等,都需要留出接口,方便外部修改。一大堆属性,对于使用者而言,并不友好,因为他并不知道哪些属性是必须的,哪些是非必须的,为了让使用者方便使用,这里单独抽离出一个配置信息类,在内部实现基础配置,同时给出方法,让外部可以修改某些属性。

class CLPasswordInputViewConfigure: NSObject {
 ///密码的位数
 var passwordNum: UInt = 6
 ///边框正方形的大小
 var squareWidth: CGFloat = 50
 ///黑点的半径
 var pointRadius: CGFloat = 18 * 0.5
 ///边距相对中间间隙倍数
 var spaceMultiple: CGFloat = 5;
 ///黑点颜色
 var pointColor: UIColor = UIColor.black
 ///边框颜色
 var rectColor: UIColor = UIColor.lightGray
 ///输入框背景颜色
 var rectBackgroundColor: UIColor = UIColor.white
 ///控件背景颜色
 var backgroundColor: UIColor = UIColor.white

 class func defaultConfig() -> CLPasswordInputViewConfigure {
  let configure = CLPasswordInputViewConfigure()
  return configure
 }
}

外部修改配置的方法,使用闭包,将基本配置回调到外部,同时在外部修改这些属性后,对内部UI进行刷新。

func updateWithConfig(config: ((CLPasswordInputViewConfigure) -> Void)?) -> Void {
  config?(self.config)
  backgroundColor = self.config.backgroundColor
  setNeedsDisplay()
 }

4.使用代理来管理各种输入相关的事件

这里单独创建一个协议,管理各种输入事件,同时通过extension实现这些协议,这样外部就可以选择性的实现这些协议,而不是必须实现。

protocol CLPasswordInputViewDelegate {
 ///输入改变
 func passwordInputViewDidChange(passwordInputView:CLPasswordInputView) -> Void
 ///点击删除
 func passwordInputViewDidDeleteBackward(passwordInputView:CLPasswordInputView) -> Void
 ///输入完成
 func passwordInputViewCompleteInput(passwordInputView:CLPasswordInputView) -> Void
 ///开始输入
 func passwordInputViewBeginInput(passwordInputView:CLPasswordInputView) -> Void
 ///结束输入
 func passwordInputViewEndInput(passwordInputView:CLPasswordInputView) -> Void
}

extension CLPasswordInputViewDelegate {
 ///输入改变
 func passwordInputViewDidChange(passwordInputView:CLPasswordInputView) -> Void {

 }
 ///点击删除
 func passwordInputViewDidDeleteBackward(passwordInputView:CLPasswordInputView) -> Void {

 }
 ///输入完成
 func passwordInputViewCompleteInput(passwordInputView:CLPasswordInputView) -> Void {

 }
 ///开始输入
 func passwordInputViewBeginInput(passwordInputView:CLPasswordInputView) -> Void {

 }
 ///结束输入
 func passwordInputViewEndInput(passwordInputView:CLPasswordInputView) -> Void {

 }
}

5.效果图

这里简单录制了一个效果,更多请参考CLDemo (本地下载)

效果图.gif

6.总结

为了方便大家学习,这里提供了OC和Swift两种语言分别实现的----->>>CLDemo (本地下载),如果对你有所帮助,欢迎Star。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • iOS输入框(UITextField)密码明暗文切换方法

    在做明暗文切换(密码输入框)的时候遇见一个坑,就是切换secureTextEntry的时候,输入框的光标会偏移,下面列出了一个解决办法及一种明暗文切换的方法 - (IBAction)pwdTextSwitch:(UIButton *)sender { // 前提:在xib中设置按钮的默认与选中状态的背景图 // 切换按钮的状态 sender.selected = !sender.selected; if (sender.selected) { // 按下去了就是明文 NSString *temp

  • iOS输入框的字数统计/最大长度限制详解

    前言 前两周我们发了一个小集「iOS 自带九宫格拼音键盘与 Emoji 表情之间的坑」,介绍了如何解决由于输入框限制 Emoji 表情的输入导致中文拼音也无法输入的问题. 后面我们又有了新需求:对输入框已输入的文本字数进行实时统计,并在界面上显示剩余字数,且不能让所输入的文本超过最大限制长度.但这个简单的功能仍然有不少小坑. 在上一个小集中,我们讲到,对于 iOS 系统自带的键盘,有时候它在输入框中填入的是占位字符(已被高亮选中起来),等用户选中键盘上的候选词时,再替换为真正输入的字符,如下:

  • 解决ios手机中input输入框光标过长的问题

    在项目中做移动端页面,发现IOS 的光标大小很大,和安卓的完全不一样,思考怎么调整大小,通过实践和尝试,找到了解决方法,现分享给大家. 修改前css部分代码: .receiving-info .receiving-info-list input { display: inline-block; width: 70%; font-size: 14px; color: #333; border: none; outline: none; line-height: 50px; } 修改后css部分代码

  • iOS实现聊天输入框功能

    经常使用微信聊天,没事儿就会想输入框的实现过程,所以抽空,也实现了一个输入框的功能: 经过封装,使用就非常的简单了,在需要的VC中,实现方法如下: - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor colorWithRed:0.92 green:0.92 blue:0.92 alpha:1.00]; self.keyView = [[DKSKeyboardView alloc] init

  • IOS 键盘挡住输入框的问题解决办法

    IOS 键盘挡住输入框的问题解决办法 在iOS开发发现一个问题,有时输入框位于低出时,当编辑输入时,弹出的键盘会挡住输入框,令用户看不清楚实时的输入情况,使界面交互极度不友好. 经过查资料终于解决了这个问题. 解决思路: 1. 输入框监听UIControlEventEditingDidBegin事件,当用户开始输入时,将整个view上移. 2. 输入框监听UIControlEventEditingDidEnd事件,当用户结束输入时,将整个view下移,恢复到原位置. 输入框监听事件: [text

  • iOS中输入框设置指定字符输入的方法

    前言 对于开发者来说,在很多情况下,一般的输入框需要按照要求进行输入,输入内容由开发人员来指定.例如:密码输入框只能输入纯数字或者是拼音与数字结合的文本等,那么我们在开发的时候就需要做一些输入文本的限时.下面话不多说了,来一起看看详细的介绍吧. 一.只能输入纯数字 在这里以UITextField为例:其实现代码如下: - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range re

  • h5 ios输入框和键盘的兼容性优化指南

    起因 h5的输入框引起键盘导致体验不好,目前就算微信.知乎.百度等产品也没有很好的技术方案实现,尤其底部固定位置的输入框各种方案都用的前提下体验也并没有很好,这个问题也是老大难问题了.目前在准备一套与native协议 来解决这个问题,目前项目中的解决方案还是有值得借鉴的地方的,分享一下 下面话不多说了,来一起看看详细的介绍吧 业务场景 固定在h5页面底部的输入框 无论是使用 <input /> 还是 <div contenteditable="true"> &l

  • iOS项目开发键盘弹出遮挡输入框问题解决方案

    在iOS或Android等移动端开发过程中,经常遇到很多需要我们输入信息的情况,例如登录时要输入账号密码.查询时要输入查询信息.注册或申请时需要填写一些信息等都是通过我们键盘来进行输入的,在iOS开发过程中,一般用于进行输入信息的有两类:UITextField和UITextView,前者是单行输入文本框,后者是可滑动的多行输入文本框,在这整个开发过程中,我们需要控制键盘的弹出和收起.在输入结束的时候获取输入的信息,此外,我们还需要保证在键盘弹起的时候不遮挡我们输入的文本框.今天,我们就主要来说一

  • iOS实现类似微信和支付宝的密码输入框(UIKeyInput协议)

    目前在项目中需要实现发红包的功能,自己就写了一个密码输入框的控件,主要用到了UIKeyInput协议和CoreGraphics框架,效果类似微信支付,感觉还行就把我的思路和制作过程写下来给大家分享一下. 让你的自定义View具备输入的功能(UIKeyInput协议) 通过UIKeyInput协议可以为响应者提供简单的键盘输入的功能,让需要键盘的responder成为第一响应者就行了.UIKeyInput协议必须实现的有三个方法,分别是以下方法: #pragma mark - UIKeyInput

  • iOS使用UIKeyInput自定义密码输入框的方法示例

    前言 开发中很多地方都会遇到密码输入,这时候往往需要根据UI设计自定义.这里遵守UIKeyInput,实现协议中的方法,让自定义View可以进行文字输入:再通过func draw(_ rect: CGRect)绘制现自定义UI:使用配置类来统一接口:使用代理来管理各种输入相关的事件.文章末尾有提供OC和Swift双语的CLDemo下载,这里讲解就使用Swift. 1.遵守UIKeyInput协议,实现文字输入 遵守UIKeyInput协议,实现协议中- (BOOL)hasText. - (voi

  • iOS 实现跑马灯效果的方法示例

    在网页开发当中跑马灯是常用到的,用来显示通知等,在游戏开发当中也如此. 首先来看看效果图: 接下来就简单看看这效果是怎么实现的. 实现方法 1.首先我们从这个图片里面能联想到如果实现这个效果必然需要使用到动画,或者还有有用scrollView的思路,这里我是用的动画的方式实现的. 2..h文件 自定义一个继承UIView的LGJAutoRunLabel类,在.h文件中: @class LGJAutoRunLabel; typedef NS_ENUM(NSInteger, RunDirection

  • PHP实现创建微信自定义菜单的方法示例

    本文实例讲述了PHP实现创建微信自定义菜单的方法.分享给大家供大家参考,具体如下: 在使用通用接口前,你需要做以下两步工作: 1.拥有一个微信公众账号,并获取到appid和appsecret(在公众平台申请内测资格,审核通过后可获得) 2.通过获取凭证接口获取到access_token 注意: access_token是第三方访问api资源的票据: access_token对应于公众号是全局唯一的票据,重复获取将导致上次获取的access_token失效. 访问下面这个地址(注意替换你的appi

  • iOS自定义PageControl的方法示例

    前言 本文主要给大家介绍了关于iOS自定义PageControl的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 自定义PageControl 我们经常会用到PageControl,但是系统的PageControl只有一种样式,不支持多样化,这里简单介绍一个简单的自定义PageControl. 主要功能: 可以自定义间隙 可以自定义高度 可以自定义选中点的宽度 每个点有点击事件 可以自定义选中和非选中的图片 可以设置居左.居中.居右样式 支持长条形状 实现: 将自定义P

  • iOS开发之自定义UITextField的方法

    UITextField是IOS开发中用户交互中重要的一个控件,常被用来做账号密码框,输入信息框等. 观察效果图 UITextField有以下几种特点: 1.默认占位文字是灰色的 2.当光标点上去时,占位文字变为白色 3.光标是白色的 接下来我们通过不同的方法来解决问题 一.将xib中的UITextField与代码关联 通过NSAttributeString方法来更改占位文字的属性 (void)viewDidLoad { [super viewDidLoad]; // Do any additio

  • 全面解析iOS应用中自定义UITableViewCell的方法

    有时候我们需要自己定义UITableViewCell的风格,其实就是向行中添加子视图.添加子视图的方法主要有两种:使用代码以及从.xib文件加载.当然后一种方法比较直观. 一.基本用法 我们这次要自定义一个Cell,使得它像QQ好友列表的一行一样:左边是一张图片,图片的右边是三行标签: 当然,我们不会搞得这么复杂,只是有点意思就行. 1.运行Xcode 4.2,新建一个Single View Application,名称为Custom Cell: 2.将图片资源导入到工程.为此,我找了14张50

  • swift 4自定义UITableCell的方法示例

    前言 本文主要给大家介绍了关于swift 4自定义UITableCell的相关内容,分享出来供大家参考学习价值,下面话不多说了,来一起看看详细的介绍吧 直接上图 新建MenuCell 创建一个类 MenuCell 继承 UITableViewCell 添加两个要实现的方法 override init(style: UITableViewCellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier:

  • 如何在Spring中自定义scope的方法示例

    大家对于 Spring 的 scope 应该都不会默认.所谓 scope,字面理解就是"作用域"."范围",如果一个 bean 的 scope 配置为 singleton,则从容器中获取 bean 返回的对象都是相同的:如果 scope 配置为prototype,则每次返回的对象都不同. 一般情况下,Spring 提供的 scope 都能满足日常应用的场景.但如果你的需求极其特殊,则本文所介绍自定义 scope 合适你. Spring 内置的 scope 默认时,所

  • Android实现自定义滑动刻度尺方法示例

    一 基础: 自定义View实现跟随手指滚动的刻度尺,实现了类似SeekBar的滑动选中效果.项目地址,欢迎star! UI图: 功能: 通过设置最小值跟最大值的范围,以及offset值.View将根据这些数据去计算出需要几个小刻度和几个长刻度,和每个长刻度上面显示的数值. 指针可以随意的定制. 当滑动停止后,刻度尺会根据四舍五入将距离指针最近的长刻度滑动到指针的位置. 支持范围越界回弹. 支持设置默认值. 二 实现: 先扯一下,再看别人写的控件的时候总有一种一脸懵逼的感觉,好多凌乱的变量和一大堆

  • 用Flutter开发自定义Plugin的方法示例

    当你在开发flutter应用的时候,有时会需要调用native的api,往往遇到flutter并没有相应的package, 这时候flutter plugin就开始发挥作用了,这篇文章将会讲解开发一个简单flutter plugin的步骤和方法,好了,让我们开始动手吧. 1.在Android Studio 中创建一个Flutter Plugin 项目,如下图 上图中你能看到项目描述中写到,如果需要暴露Andorid或iOS的API给开发者时,选择"Plugin"项目类型. 这个项目我们

随机推荐