• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

[Swift实际操作]九、完整实例-(8)登录页面:创建自定义表单Row以及控制器 ...

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

本文将为你演示,如何知错自定义的表单行,表单行包含一个输入框和错误提示标签。

用于登录、注册以及其他需要表单的页面。

【New File】->【Cocoa Touch Class】创建新文件【FormRow.swift】

Name:FormRow

Subclass:UIView

Language:Swift

接着开始编写代码,完成自定义表单行的创建。

  1 import UIKit
  2 //定义一个枚举类型,表示表单中的输入框的类型,共5种
  3 enum FieldType
  4 {
  5     //手机
  6     case Tel
  7     //邮箱
  8     case Email
  9     //密码
 10     case Password
 11     //验证码
 12     case VerifyCode
 13     //昵称
 14     case NickName
 15 }
 16 
 17 //定义一个结构体类型
 18 struct RegexHelper
 19 {
 20     //添加一个正则表达式常量
 21     let regex: NSRegularExpression?
 22     //并添加一个初始化方法
 23     init(_ pattern: String)
 24     {
 25         //接着通过一个异常捕捉语句,
 26         do
 27         {
 28             //初始化一个正则表达式
 29             //并设置进行判断时,不区分英文字母的大小写
 30             regex = try NSRegularExpression(pattern: pattern, options: NSRegularExpression.Options.caseInsensitive)
 31         }
 32         catch
 33         {
 34             regex = nil
 35         }
 36     }
 37 
 38     //添加一个方法
 39     //使用正则表达式,对字符串进行匹配,并返回匹配的结果
 40     func match(_ input: String) -> Bool
 41     {
 42         //初始化一个范围常量
 43         let len = input.characters.count
 44         let range = NSMakeRange(0, len)
 45         //使用正则表达式,对字符串进行匹配,并返回匹配的结果
 46         if let matches = regex?.matches(in: input,
 47                                         options: .reportProgress,
 48                                         range: range)
 49         {
 50             return matches.count > 0
 51         }
 52         else
 53         {
 54             return false
 55         }
 56     }
 57 }
 58 
 59 //给当前的类添加一个文本框协议,用来实现对文本框输入时检测
 60 class FormRow: UIView, UITextFieldDelegate {
 61     //初始化一个布尔变量,用来标识文本框的内容是否符合规则
 62     var isPass : Bool = false
 63     //依次初始化4个组件:1、显示文本框的标题
 64     var labelTitle : UILabel!
 65     //依次初始化4个组件:2、显示错误提示信息
 66     var labelError : UILabel!
 67     //依次初始化4个组件:3、输入框
 68     var inputField : UITextField!
 69     //依次初始化4个组件:4、分割线
 70     var line : UIView!
 71     //初始化一个视图控制器属性,
 72     //该属性的类文件将在后面创建
 73     weak var controller : BaseLoginRegViewController!
 74     //第一个属性:表示文本框的默认类型
 75     var valueType : FieldType = FieldType.Tel //0:tel, 1:email, 2:password  3:verifycode  4:username
 76     //第二个属性:表示正确的验证码
 77     var correctVerifyCode = ""
 78     //第三个属性:表示错误提示标签的显示区域
 79     var frameError : CGRect!
 80 
 81     //重写视图类的初始化方法
 82     override init(frame: CGRect) {
 83         super.init(frame: frame)
 84         //初始化一个指定显示区域的标签对象
 85         let frameTitle = CGRect(x: 20, y: 0, width: frame.size.width-40, height: 20)
 86         labelTitle = UILabel(frame: frameTitle)
 87         //设置标签的文字颜色
 88         labelTitle.textColor = .white
 89         //设置标签的字体属性
 90         labelTitle.font = UIFont(name: "PingFang SC", size: 14)
 91         //并将标签添加到自定义视图
 92         self.addSubview(labelTitle)
 93         //初始化一个指定显示区域的文本输入框
 94         let frameInput = CGRect(x: 20, y: 20, width: frame.size.width-40, height: 40)
 95         inputField = UITextField(frame: frameInput)
 96         //设置输入框的代理
 97         inputField.delegate = self
 98         //设置输入框的字体颜色
 99         inputField.textColor = .white
100         //设置输入框的清除按钮的模式
101         inputField.clearButtonMode = .whileEditing
102         //设置输入框的字体属性
103         inputField.font = UIFont(name: "PingFang SC", size: 17)
104         //并将输入框添加到自定义视图
105         self.addSubview(inputField)
106         //初始化一个具有白色背景的视图对象,作为表单行之间的分割线
107         line = UIView(frame: CGRect(x: 20, y: 64, width: frame.size.width-40, height: 1))
108         line.backgroundColor = UIColor.white
109         self.addSubview(line)
110         //初始化一个标签对象,用来在用户输入错误时显示提示信息
111         frameError = CGRect(x: 20, y: 69, width: frame.size.width-40, height: 14)
112         labelError = UILabel(frame: frameError)
113         //设置标签的文字颜色
114         labelError.textColor = UIColor(red: 255.0/255, green: 89.0/255, blue: 95.0/255, alpha: 1.0)
115          //设置标签的字体属性
116         labelError.font = UIFont(name: "PingFang SC", size: 10)!
117         //默认情况下,错误标签处于隐藏状态
118         labelError.isHidden = true
119         self.addSubview(labelError)
120         //添加一个通知,用来检测输入框种的内容发生变化时的事件
121         NotificationCenter.default.addObserver(self,
122                                                selector: #selector(FormRow.enteringContent(_:)),
123                                                name: NSNotification.Name.UITextFieldTextDidChange,
124                                                object: nil)
125     }
126 
127     //添加一个实例方法,用来获得输入框中的文字
128     func getValue() -> String
129     {
130         return inputField.text!
131     }
132 
133     //添加一个方法,用来设置自定义视图中的输入框的类型
134     func setValueType(type : FieldType)
135     {
136         self.valueType = type
137         //当类型为电话号码时
138         if(type == .Tel)
139         {
140             //设置输入框的键盘类型
141             self.inputField.keyboardType = UIKeyboardType.phonePad
142              //设置输入框的标题文字
143             self.labelTitle.text = "电话号码"
144             
145         }
146         //当类型为邮箱时
147         else if(type == .Email)
148         {
149              //设置输入框的键盘类型
150             self.inputField.keyboardType = UIKeyboardType.emailAddress
151             //设置输入框的标题文字
152             self.labelTitle.text = "邮箱地址"
153         }
154         //当类型为密码时
155         else if(type == .Password)
156         {
157              //设置输入框的键盘类型
158             self.inputField.keyboardType = UIKeyboardType.URL
159              //设置密文输入
160             self.inputField.isSecureTextEntry = true
161              //设置输入框的标题文字
162             self.labelTitle.text = "密码"
163         }
164         //当类型为验证码时
165         else if(type == .VerifyCode)
166         {
167             //设置输入框的键盘类型
168             self.inputField.keyboardType = UIKeyboardType.numberPad
169             //设置输入框的标题文字
170             self.labelTitle.text = "验证码"
171         }
172         //当类型为昵称时
173         else if(type == .NickName)
174         {
175             //设置输入框的键盘类型
176             self.inputField.keyboardType = UIKeyboardType.namePhonePad
177             //设置输入框的标题文字
178             self.labelTitle.text = "用户昵称"
179         }
180     }
181 
182     //添加一个方法,用来判断输入框中的内容是否为空
183     func checkIsNotBlank()
184     {
185         if self.getValue() != ""
186         {
187             //当值不为空时,设置布尔属性的值为真
188             self.isPass = true
189             //接着调用控制器对象的校验表单功能
190             self.controller.checkForm()
191         }
192         else
193         {
194             //当值为空时,设置布尔属性的值为真,
195             self.isPass = false
196             //接着调用控制器对象的校验表单功能 
197             self.controller.checkForm()
198         }
199     }
200 
201     //添加一个方法,用来对输入框的内容进行检验,
202     //并返回布尔类型的结果
203     func checkValue() -> Bool
204     {
205         //处理类型为电话号码时的情况
206         if(self.valueType == .Tel)
207         {
208             //设置用来匹配电话号码的正则表达式字符串
209             let pattern = "^1[0-9]{10}$"
210             //并初始化一个正则匹配的结构体对象
211             let matcher = RegexHelper(pattern)
212             //对输入框中的内容进行匹配,
213             if !matcher.match(self.getValue())
214             {
215                 //并返回输入失败时的结果
216                 self.setError(info: "电话号码输入有误")
217                 return false
218             }
219         }
220         //处理类型为电子邮箱时的情况
221         else if(self.valueType == .Email)
222         {
223             //设置用来匹配电子邮箱的正则表达式字符串
224             let pattern = "^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$"
225             //并初始化一个正则匹配的结构体对象
226             let matcher = RegexHelper(pattern)
227             //对输入框中的内容进行匹配,
228             let value = self.getValue()
229             if !matcher.match(value)
230             {
231                 //并返回输入失败时的结果
232                 self.setError(info: "邮箱地址输入有误")
233                 return false
234             }
235         }
236          //处理类型为密码时的情况
237         else if(self.valueType == .Password)
238         {
239             //设置用来匹配密码的正则表达式字符串
240             let pattern = "^[a-z0-9_-]{6,16}$"
241             //并初始化一个正则匹配的结构体对象
242             let matcher = RegexHelper(pattern)
243              //对输入框中的内容进行匹配,
244             if !matcher.match(self.getValue())
245             {
246                  //并返回输入失败时的结果
247                 self.setError(info: "密码输入有误")
248                 return false
249             }
250         }
251         //处理类型为验证码时的情况   
252         else if(self.valueType == .VerifyCode)
253         {
254              //设置用来匹配验证码的正则表达式字符串
255             let pattern = "^[0-9]{6,6}$"
256             //并初始化一个正则匹配的结构体对象
257             let matcher = RegexHelper(pattern)
258             //对输入框中的内容进行匹配,
259             if !matcher.match(self.getValue())
260             {
261                 //并返回输入失败时的结果
262                 self.setError(info: "验证码输入有误")
263                 return false
264             }
265         }
266         //处理类型为昵称时的情况
267         else if(self.valueType == .NickName)
268         {
269             //设置用来匹配昵称的正则表达式字符串
270             let pattern = "^[0-9_-a-zA-Z\\u4E00-\\u9FA5]{2,100}$"
271             //并初始化一个正则匹配的结构体对象
272             let matcher = RegexHelper(pattern)
273             //对输入框中的内容进行匹配,
274             if !matcher.match(self.getValue())
275             {
276                 //并返回输入失败时的结果
277                 self.setError(info: "用户名称输入有误")
278                 return false
279             }
280         }
281         //当执行到方法的末尾时,表示匹配成功,
282         //此时设置自定义表单行的状态,
283         self.setSuccess()
284         //并返回值为真的结果
285         return true
286     }
287 
288     //添加一个方法,用来设置自定义表单行在匹配错误时的状态
289     func setError(info : String)
290     {
291         //设置错误标签的内容
292         self.isPass = false
293         self.labelError.text = info
294         //并显示错误标签
295         self.labelError.isHidden = false
296         //由于错误标签是通过动画来显示的,
297         //所以在此对错误标签的显示区域和透明度进行初始化
298         let rect = CGRect(x: frameError.origin.x, y: frameError.origin.y - 20, width: frameError.size.width, height: frameError.size.height)
299         self.labelError.frame = rect
300         self.labelError.layer.opacity = 0.0
301         //设置标题颜色
302         self.labelTitle.textColor = .white
303         //设置输入框文字颜色
304         self.inputField.textColor = .white
305         //设置分割线的背景颜色
306         self.line.backgroundColor = .white
307         //使用视图的类方法,开始执行一段动画
308         UIView.beginAnimations("switchToDaLu", context: nil)
309         //并设置动画的时长为0.6秒
310         UIView.setAnimationDuration(0.6)
311         //在动画块中,更改动画标签的透明度
312         self.labelError.layer.opacity = 1.0
313         //在动画块中,更改动画标签的显示区域
314         self.labelError.frame = self.frameError
315         //修改标题颜色
316         self.labelTitle.textColor = self.labelError.textColor
317         //修改输入框文字颜色
318         self.inputField.textColor = self.labelError.textColor
319         //修改分割线的背景颜色
320         self.line.backgroundColor = self.labelError.textColor
321         //以上外观的变化,都以动画的形式,在0.63秒之内完成。
322         UIView.commitAnimations()
323         //最后结束视图的动画块
324         self.controller.checkForm()
325     }
326 
327     //添加一个方法,用来设置自定义表单行在匹配成功时的状态
328     func setSuccess()
329     {
330         //在上一个方法种,是通过视图动画块的方式创建动画的,
331         //在当前方法种,你将通过闭包的方式,创建一个动画。
332         //同时在动画结束时,隐藏错误标签
333         UIView.animate(withDuration: 0.6, delay: 0.0, options: .curveLinear, animations: {
334             
335             self.isPass = true
336             //初始化一个范围对象,作为错误标签的起始位置
337             let rect = CGRect(x: self.frameError.origin.x, y: self.frameError.origin.y - 20, width: self.frameError.size.width, height: self.frameError.size.height)
338             //将错误标签移至起始位置,并设置不透明度为0
339             self.labelError.frame = rect
340             self.labelError.layer.opacity = 0.0
341             //修改标题颜色
342             self.labelTitle.textColor = .white
343             //设置输入框文字颜色
344             self.inputField.textColor = .white
345             //设置分割线的背景颜色
346             self.line.backgroundColor = .white
347             //对控制器种的所有表单行进行校验
348             self.controller.checkForm()
349             
350         }, completion: { finished in
351          //同时在动画结束时,隐藏错误标签
352             self.labelError.isHidden = true
353         })
354     }
355 
356     //添加一个协议方法,用来监听输入框开始编辑的事件
357     func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
358         
359         self.controller.focusedFieldType = self.valueType
360         
361         return true
362     }
363 
364     //继续添加一个来自协议的方法,用来监听输入框的内容发生变化时的事件
365     func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
366         //将输入框右侧的删除图标的颜色进行修改,将其颜色变亮。
367         let count = inputField.subviews.count
368         
369         if count >= 2
370         {
371             let bt = inputField.subviews[1] as! UIButton
372             bt.imageView?.image = bt.imageView?.image?.blendColor(.white, blendMode: .destinationIn)
373         }
374         //当类型为密码时,最多允许输入11个字符
375         var maxNum = 11
376         if(self.valueType == .Password)
377  
                       
                    
                    

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
今日份swift学习5发布时间:2022-07-14
下一篇:
Swift版本的Framework中,使用OC桥接报错发布时间:2022-07-14
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap