Commit 3e94e17c authored by Steven杜宇's avatar Steven杜宇

// 验证码输入

parent 0905ace5
......@@ -11,6 +11,9 @@
04F526C12B3A657000FC6CE6 /* YHValidateCodeInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04F526C02B3A657000FC6CE6 /* YHValidateCodeInputView.swift */; };
04F526C72B3BB94200FC6CE6 /* YHSMSCodeInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04F526C32B3BB94200FC6CE6 /* YHSMSCodeInputView.m */; };
04F526C82B3BB94200FC6CE6 /* YHSMSCodeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04F526C42B3BB94200FC6CE6 /* YHSMSCodeView.m */; };
04F526CA2B3E92E200FC6CE6 /* Algorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04F526C92B3E92E200FC6CE6 /* Algorithm.swift */; };
04F526CC2B3E962400FC6CE6 /* YNSmsCodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04F526CB2B3E962400FC6CE6 /* YNSmsCodeView.swift */; };
04F526CE2B3EA80300FC6CE6 /* YHSmsCodeInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04F526CD2B3EA80300FC6CE6 /* YHSmsCodeInputView.swift */; };
04FAC5432B32BA5F00D24B36 /* YHHomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04FAC5422B32BA5F00D24B36 /* YHHomeViewController.swift */; };
04FAC5452B32BA7000D24B36 /* YHMyViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04FAC5442B32BA7000D24B36 /* YHMyViewController.swift */; };
04FAC54A2B32CF1000D24B36 /* YHNetRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04FAC5492B32CF1000D24B36 /* YHNetRequest.swift */; };
......@@ -89,6 +92,9 @@
04F526C42B3BB94200FC6CE6 /* YHSMSCodeView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YHSMSCodeView.m; sourceTree = "<group>"; };
04F526C52B3BB94200FC6CE6 /* YHSMSCodeInputView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YHSMSCodeInputView.h; sourceTree = "<group>"; };
04F526C62B3BB94200FC6CE6 /* YHSMSCodeView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YHSMSCodeView.h; sourceTree = "<group>"; };
04F526C92B3E92E200FC6CE6 /* Algorithm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Algorithm.swift; sourceTree = "<group>"; };
04F526CB2B3E962400FC6CE6 /* YNSmsCodeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YNSmsCodeView.swift; sourceTree = "<group>"; };
04F526CD2B3EA80300FC6CE6 /* YHSmsCodeInputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHSmsCodeInputView.swift; sourceTree = "<group>"; };
04FAC5422B32BA5F00D24B36 /* YHHomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHHomeViewController.swift; sourceTree = "<group>"; };
04FAC5442B32BA7000D24B36 /* YHMyViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHMyViewController.swift; sourceTree = "<group>"; };
04FAC5492B32CF1000D24B36 /* YHNetRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHNetRequest.swift; sourceTree = "<group>"; };
......@@ -182,6 +188,7 @@
04F526C02B3A657000FC6CE6 /* YHValidateCodeInputView.swift */,
04FAC5502B3ABA5000D24B36 /* YHLoginStyleButton.swift */,
04FAC5522B3AC6F200D24B36 /* YHLoginPrivacyView.swift */,
04F526C92B3E92E200FC6CE6 /* Algorithm.swift */,
);
path = V;
sourceTree = "<group>";
......@@ -201,6 +208,8 @@
04F526C42B3BB94200FC6CE6 /* YHSMSCodeView.m */,
04F526C52B3BB94200FC6CE6 /* YHSMSCodeInputView.h */,
04F526C62B3BB94200FC6CE6 /* YHSMSCodeView.h */,
04F526CB2B3E962400FC6CE6 /* YNSmsCodeView.swift */,
04F526CD2B3EA80300FC6CE6 /* YHSmsCodeInputView.swift */,
);
path = "验证码输入框";
sourceTree = "<group>";
......@@ -675,10 +684,12 @@
A52DF24D2B33177F006618D6 /* BsHUDWariningView.swift in Sources */,
A52DF0C32B330A20006618D6 /* BsCacheTool.swift in Sources */,
A52DF24A2B33177F006618D6 /* BsHUDContainerView.swift in Sources */,
04F526CC2B3E962400FC6CE6 /* YNSmsCodeView.swift in Sources */,
A52DF0BD2B330A20006618D6 /* YHBaseUrlManager.swift in Sources */,
A52DF2342B330A21006618D6 /* BsBaseModel.swift in Sources */,
04FAC54D2B3A9E3D00D24B36 /* YHConfig.swift in Sources */,
04F526C82B3BB94200FC6CE6 /* YHSMSCodeView.m in Sources */,
04F526CE2B3EA80300FC6CE6 /* YHSmsCodeInputView.swift in Sources */,
04F526AF2B32D4B600FC6CE6 /* YHPersonalCenterCell.swift in Sources */,
A52DF23B2B330A21006618D6 /* YHNoDataTipView.swift in Sources */,
A52DF23F2B3316A0006618D6 /* YHBasicContentView.swift in Sources */,
......@@ -692,6 +703,7 @@
A52DF0C62B330A20006618D6 /* UIColor-Extension.swift in Sources */,
A52DF0D02B330A20006618D6 /* UILable-Extension.swift in Sources */,
04FAC5432B32BA5F00D24B36 /* YHHomeViewController.swift in Sources */,
04F526CA2B3E92E200FC6CE6 /* Algorithm.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
......@@ -31,8 +31,8 @@ class YHMyViewController: YHBaseViewController, ConstraintRelatableTarget {
return tableView
}()
lazy var smsInputView: YHSMSCodeInputView = {
let codeView = YHSMSCodeInputView(frame: CGRectZero)
lazy var smsInputView: YHSmsCodeInputView = {
let codeView = YHSmsCodeInputView(config: YHSmsCodeViewConfig())
return codeView
}()
......
//
// Algorithm.swift
// galaxy
//
// Created by edy on 2023/12/29.
//
import UIKit
class Node<T> {
var value: T
var next: Node<T>?
init(value: T, next: Node<T>? = nil) {
self.value = value
self.next = next
}
}
struct LinkList<T>: CustomStringConvertible {
var head : Node<T>?
var tail : Node<T>?
var isEmpty : Bool {
head == nil
}
var description : String {
var desc = ""
var node = head
while node != nil {
desc += "\(node!.value)->"
node = node!.next
}
desc += "head:\(head?.value) tail:\(tail?.value)"
return desc
}
mutating func push(_ value : T) {
// 此乃头插法
head = Node(value: value, next: head)
if tail == nil {
tail = head
}
}
mutating func append(_ value : T) {
// 此乃尾插法
let node = Node(value: value)
tail?.next = node
tail = node
if head == nil {
head = node
}
}
mutating func pop() -> T? {
// 此乃头删法
// defer 所声明的 block 会在当前代码执行return退出后被调用
defer {
head = head?.next
if isEmpty {
tail = nil
}
}
return head?.value
}
mutating func removeLast() -> T? {
// 此乃尾删法
// 头结点为空直接返回
guard let head = head else {return nil}
// 只有一个节点
guard let _ = head.next else {return pop()}
// 以下情况是链表有不小于2个节点的case
var currentNode = head
var previousNode = head
while let next = currentNode.next {
previousNode = currentNode
currentNode = next
}
previousNode.next = nil
tail = previousNode
return currentNode.value
}
// 反转链表 (非递归)
mutating func reveseLinkList() -> LinkList<T> {
guard let _ = head else { return self }
guard let _ = head?.next else { return self }
// 以下情况是链表有不小于2个节点的case
var previous : Node<T>? = nil
var current = head
tail = head
while current != nil {
let next = current?.next
current?.next = previous
previous = current
current = next
}
head = previous
return self
}
mutating func rr() {
tail = head;
head = reverse(head);
}
// 反转链表(递归)
mutating func reverse(_ node : Node<T>?)-> Node<T>? {
if node == nil || node?.next == nil { return node }
let newHead = reverse(node?.next)
node?.next?.next = node
node?.next = nil
return newHead
}
}
class TreeNode<T> {
var value : T
var left : TreeNode<T>? = nil
var right : TreeNode<T>? = nil
init(value: T, left: TreeNode<T>? = nil, right: TreeNode<T>? = nil) {
self.value = value
self.left = left
self.right = right
}
// 翻转树
func reverseBinaryTree(_ node : TreeNode?) -> TreeNode? {
guard let _ = node else { return node}
var leftNode = node?.left
node?.left = reverseBinaryTree(node?.right)
node?.right = reverseBinaryTree(leftNode)
return node
}
// 求二叉树的节点个数
func getTreeNodeNum(_ node : TreeNode<T>?) -> Int {
if node == nil { return 0 }
return getTreeNodeNum(node?.left) + getTreeNodeNum(node?.right) + 1
}
// 二叉树的最小深度
func getMinDepth(_ node : TreeNode<T>?) -> Int {
if node == nil { return 0 }
let leftMin = getMinDepth(node!.left)
let rightMin = getMinDepth(node!.right)
// 此处很精髓
if node!.left == nil || node!.right == nil { return leftMin+rightMin+1 }
return min(leftMin, rightMin) + 1;
}
// 二叉树的最大深度
func getMaxDepth(_ node : TreeNode<T>?) -> Int {
if node == nil { return 0 }
// 此处注意和求最小深度的差别
return max(getMaxDepth(node?.left) , getMaxDepth(node?.right)) + 1
}
// 归并树
func mergeBinaryTree(_ left : TreeNode<Int>?, _ right : TreeNode<Int>?) -> TreeNode<Int>? {
if left == nil {
return right
}
if right == nil {
return left
}
var mergeNode = TreeNode<Int>(value: (left!.value + right!.value))
mergeNode.left = mergeBinaryTree(left!.left, right!.left)
mergeNode.right = mergeBinaryTree(left!.right, right!.right)
return mergeNode
}
}
//
// YHSmsCodeInputView.swift
// galaxy
//
// Created by edy on 2023/12/29.
//
import UIKit
// 输入框UI显示配置
struct YHSmsCodeViewConfig {
var textColor : UIColor? = .white
var bgColor : UIColor? = .init(white: 1, alpha: 0.3)
var cursorColor : UIColor? = .black
var font: UIFont? = .systemFont(ofSize: 20)
// 展示输入框个数
var count : Int = 3
var width : Double = 60.0
var height : Double = 60.0
// 输入框之间间距
var gap:Double = 8
}
let codeViewBaseTag = 9527
class YHSmsCodeInputView: UIView {
var smsCode: String?
var config: YHSmsCodeViewConfig = YHSmsCodeViewConfig()
// 此输入框并不显示,只是接收输入
lazy var textField: UITextField = {
let textField = UITextField()
textField.backgroundColor = .clear
textField.tintColor = .clear
textField.delegate = self
textField.addTarget(self, action: #selector(smsCodeInputChanged), for: .editingChanged)
return textField
}()
convenience init(config: YHSmsCodeViewConfig) {
self.init(frame: .zero)
self.config = config
self.setupUI()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
func setupUI() {
self .addSubview(textField)
textField.snp.makeConstraints { make in
make.edges.equalTo(self)
}
// 输入框数量
let count = config.count
// 输入框之间间距
let gap = config.gap
// 输入框宽度
let inputWidth = config.width
// 输入框高度
let inputHeight = config.height
// 输入框个数是否为偶数
let isEven = (config.count % 2 == 0)
for index in 1...count {
let inputView = YNSmsCodeView(frame: CGRectZero)
inputView.tag = codeViewBaseTag + index
self.addSubview(inputView)
// 小组件右边距离父视图中轴线间距
var rightMargin = 0.0;
if (isEven) { // 输入框个数为偶数
let middle = count/2
if (index <= middle) {
rightMargin = -(Double(middle-index)*(gap+inputWidth) + gap/2.0)
} else {
rightMargin = Double(index-middle-1)*(gap+inputWidth) + gap/2.0+inputWidth
}
print(rightMargin)
inputView.snp.makeConstraints { make in
make.size.equalTo(CGSize(width: inputWidth, height: inputHeight))
make.centerY.equalTo(self)
make.right.equalTo(self.snp.centerX).offset(rightMargin)
}
} else { // // 输入框个数为奇数
let middle:Int = count/2 + 1
if (index < middle) {
rightMargin = -(Double(middle-index-1)*(gap+inputWidth) + inputWidth/2.0+gap)
} else if (index > middle) {
rightMargin = (Double(index-middle-1)*(gap+inputWidth) + inputWidth*3/2.0+gap)
}
print(rightMargin)
inputView.snp.makeConstraints { make in
make.size.equalTo(CGSize(width: inputWidth, height: inputHeight))
make.centerY.equalTo(self)
if (index == middle) {
make.centerX.equalTo(self)
} else {
make.right.equalTo(self.snp.centerX).offset(rightMargin)
}
}
}
}
}
@objc func smsCodeInputChanged(input:UITextField) {
if input.text == nil { return }
for (index, char) in input.text!.enumerated() {
if (index < config.count) {
var codeView = self.viewWithTag(codeViewBaseTag+index+1) as? YNSmsCodeView
codeView?.text = String(char)
}
}
for index in (0 ..< config.count) {
if index < input.text?.count {
}
}
}
}
extension YHSmsCodeInputView: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return true
}
}
//
// YNSmsCodeView.swift
// galaxy
//
// Created by edy on 2023/12/29.
//
import UIKit
class YNSmsCodeView: UIView {
// 是否显示光标
var showCursor : Bool = false {
didSet {
if (showCursor) {
UIView.animate(withDuration: 0.5, animations: {
[weak self] in
self?.cursor.isHidden = false
}, completion: {
[weak self] finishd in
UIView.animate(withDuration: 0.5, animations: {
self?.cursor.isHidden = true
})
})
} else {
cursor.layer.removeAllAnimations()
cursor.isHidden = true
}
}
}
var text : String? {
didSet {
label.text = text
}
}
lazy var label : UILabel = {
let label = UILabel()
label.textColor = .white
label.textAlignment = .center
label.font = UIFont.systemFont(ofSize: 20)
return label
}()
var cursor : UIView = {
let cursor = UIView()
cursor.backgroundColor = .black
cursor.alpha = 0
return cursor
}()
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override init(frame: CGRect) {
super.init(frame: frame)
self.config()
}
func config() {
self.isUserInteractionEnabled = false
self.layer.cornerRadius = 6;
self.clipsToBounds = true;
self.backgroundColor = UIColor(white: 1, alpha: 0.3)
self.addSubview(label)
self.addSubview(cursor)
}
override func layoutSubviews() {
// let x = (self.frame.size.width - self.label.frame.size.width) / 2.0;
// let y = (self.frame.size.height - self.label.frame.size.height) / 2.0;
self.label.frame = self.bounds
self.cursor.bounds = CGRectMake(0, 0, 1.5, self.frame.size.height - 20);
self.cursor.center = CGPoint(x:CGRectGetMidX(self.bounds) , y: CGRectGetMidY(self.bounds))
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment