[Swift通天遁地]二、表格表单-(18)快速应用多种预定义格式的表单验证
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/10202590.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
本文将演示表单在提交时的数据验证。
在项目导航区,打开视图控制器的代码文件【ViewController.swift】
现在开始编写代码,给表单添加验证的功能。
1 import UIKit 2 //首先在当前类文件中, 3 //引入以及安装的第三方类库 4 import Eureka 5 6 //修改当前视图控制器类的父类的名称 7 class ViewController: FormViewController { 8 9 override func viewDidLoad() { 10 super.viewDidLoad() 11 12 //设置当验证失败时,标签行的视觉刷新事件 13 LabelRow.defaultCellUpdate = 14 { 15 cell, row in 16 //设置背景颜色为红色 17 cell.contentView.backgroundColor = .red 18 //设置字体的颜色为白色 19 cell.textLabel?.textColor = .white 20 //设置字体的样式 21 cell.textLabel?.font = UIFont.boldSystemFont(ofSize: 13) 22 //设置文字的对齐方式 23 cell.textLabel?.textAlignment = .right 24 } 25 //设置文本行的视觉变化 26 TextRow.defaultCellUpdate = 27 { 28 cell, row in 29 //当验证失败时 30 if !row.isValid 31 { 32 //设置字体的颜色为红色 33 cell.titleLabel?.textColor = .red 34 } 35 } 36 37 38 form 39 //在表单中添加一个段落,并设置段落的头部和尾部信息 40 +++ Section(header: "Required Rule", 41 footer: "Options: Validates on change") 42 //在该段落中添加一个文本 43 <<< TextRow() 44 { 45 //设置本行的标题文字 46 $0.title = "Required Rule" 47 //添加验证的规则为非空, 48 //如果该行的内容为空,则会提示验证错误。 49 $0.add(rule: RuleRequired()) 50 //设置值发生变化时进行验证 51 $0.validationOptions = .validatesOnChange 52 } 53 54 //在表单中添加一个段落,并设置段落的头部和尾部信息 55 +++ Section(header: "Email Rule, Required Rule", 56 footer: "Options: Validates on change after blurred") 57 58 //在该段落中添加一个文本 59 <<< TextRow() 60 { 61 //设置本行的标题文字 62 $0.title = "Email Rule" 63 //添加验证的规则为非空, 64 //如果该行的内容为空,则会提示验证错误。 65 $0.add(rule: RuleRequired()) 66 //创建一个字符串类型的规则集合 67 var ruleSet = RuleSet<String>() 68 //添加非空验证 69 ruleSet.add(rule: RuleRequired()) 70 //添加邮箱验证 71 ruleSet.add(rule: RuleEmail()) 72 //将规则集合赋予当前的表单行 73 $0.add(ruleSet: ruleSet) 74 //设置当失去焦点,并且内容发生变化时,进行表单的验证。 75 $0.validationOptions = .validatesOnChangeAfterBlurred 76 } 77 78 //在表单中添加一个段落,并设置段落的头部和尾部信息 79 +++ Section(header: "URL Rule", 80 footer: "Options: Validates on change") 81 82 //添加一个网址行 83 <<< URLRow() 84 { 85 //设置本行的标题文字 86 $0.title = "URL Rule" 87 //添加网址格式的验证 88 $0.add(rule: RuleURL()) 89 //设置值发生变化时进行验证 90 $0.validationOptions = .validatesOnChange 91 } 92 //设置单元格的刷新动作 93 .cellUpdate 94 { 95 cell, row in 96 //当验证失败时 97 if !row.isValid 98 { 99 //设置单元格的字体颜色为红色 100 cell.titleLabel?.textColor = .red 101 } 102 } 103 104 //在表单中添加一个段落,并设置段落的头部和尾部信息 105 +++ Section(header: "MinLength 8 Rule, MaxLength 13 Rule", 106 footer: "Options: Validates on blurred") 107 //添加一个密码行 108 <<< PasswordRow() 109 { 110 //设置本行的标题文字 111 $0.title = "Password" 112 //添加验证规则: 113 //设置最小长度为8 114 $0.add(rule: RuleMinLength(minLength: 8)) 115 //设置最大长度为13 116 $0.add(rule: RuleMaxLength(maxLength: 13)) 117 //用户需要输入最小长度和最大长度之间的内容 118 } 119 //设置单元格的刷新动作 120 .cellUpdate 121 { 122 cell, row in 123 //当验证失败时 124 if !row.isValid 125 { 126 //设置单元格的字体颜色为红色 127 cell.titleLabel?.textColor = .red 128 } 129 } 130 131 //添加一个段落,并设置段落的头部和尾部的信息 132 +++ Section(header: "Should be GreaterThan 2 and SmallerThan 999", 133 footer: "Options: Validates on blurred") 134 135 //添加一个整数行 136 <<< IntRow() 137 { 138 //设置本行的标题文字 139 $0.title = "Range Rule" 140 //添加验证规则:允许用户输入2~999之间的整数 141 $0.add(rule: RuleGreaterThan(min: 2)) 142 $0.add(rule: RuleSmallerThan(max: 999)) 143 } 144 //设置单元格的刷新动作 145 .cellUpdate 146 { 147 cell, row in 148 //当验证失败时 149 if !row.isValid 150 { 151 //设置单元格的字体颜色为红色 152 cell.titleLabel?.textColor = .red 153 } 154 } 155 156 //添加一个段落,并设置段落的头部和尾部的信息 157 +++ Section(header: "Match field values", footer: "Options: Validates on blurred") 158 159 //添加一个密码行 160 <<< PasswordRow("password") 161 { 162 //设置本行的标题文字 163 $0.title = "Password" 164 } 165 //添加一个密码行 166 <<< PasswordRow() 167 { 168 //设置本行的标题文字 169 $0.title = "Confirm Password" 170 //添加验证规则:设置长度为8~13 171 $0.add(rule: RuleMinLength(minLength: 8)) 172 $0.add(rule: RuleMaxLength(maxLength: 13)) 173 } 174 //设置单元格的刷新动作 175 .cellUpdate 176 { cell, row in 177 //当验证失败时 178 if !row.isValid 179 { 180 //设置单元格的字体颜色为红色 181 cell.titleLabel?.textColor = .red 182 } 183 } 184 185 //添加一个段落,并设置段落的头部和尾部的信息 186 +++ Section(header: "More sophisticated validations UX using callbacks", footer: "") 187 188 //添加一个文本行 189 <<< TextRow() 190 { 191 //设置本行的标题文字 192 $0.title = "Required Rule" 193 //添加验证规则:非空 194 $0.add(rule: RuleRequired()) 195 //设置值发生变化时进行验证 196 $0.validationOptions = .validatesOnChange 197 } 198 //设置单元格的刷新动作 199 .cellUpdate 200 { 201 cell, row in 202 //当验证失败时 203 if !row.isValid 204 { 205 //设置单元格的字体颜色为红色 206 cell.titleLabel?.textColor = .red 207 } 208 } 209 //设置单元格的在验证发生变化时的情况 210 .onRowValidationChanged 211 { 212 cell, row in 213 //获得当前表单行在表单中的序号 214 let rowIndex = row.indexPath!.row 215 //遍历 216 while row.section!.count > rowIndex + 1 && row.section?[rowIndex + 1] is LabelRow 217 { 218 //删除当前段落的错误信息标签 219 row.section?.remove(at: rowIndex + 1) 220 } 221 //当验证失败时 222 if !row.isValid 223 { 224 //对所有的错误信息进行遍历 225 for (index, validationMsg) in row.validationErrors.map({ $0.msg }).enumerated() 226 { 227 //创建一个标签表单行 228 let labelRow = LabelRow() 229 { 230 //设置本行的标题文字为错误信息 231 $0.title = validationMsg 232 //同时设置单元格的高度 233 $0.cell.height = { 30 } 234 } 235 //将标签行,插入到当前行的下方 236 row.section?.insert(labelRow, at: row.indexPath!.row + index + 1) 237 } 238 } 239 } 240 //添加一个邮箱表单行 241 <<< EmailRow() 242 { 243 //设置本行的标题文字 244 $0.title = "Email Rule" 245 //添加验证规则: 246 //非空规则 247 $0.add(rule: RuleRequired()) 248 //邮箱格式规则 249 $0.add(rule: RuleEmail()) 250 //设置当失去焦点,并且内容发生变化时进行表单的验证。 251 $0.validationOptions = .validatesOnChangeAfterBlurred 252 } 253 //设置单元格的刷新动作 254 .cellUpdate 255 { 256 cell, row in 257 //当验证失败时 258 if !row.isValid 259 { 260 //设置单元格的字体颜色为红色 261 cell.titleLabel?.textColor = .red 262 } 263 } 264 //处理单元格在验证发生变化时的情况 265 .onRowValidationChanged 266 { 267 cell, row in 268 //获得当前表单行在表单中的序号 269 let rowIndex = row.indexPath!.row 270 while row.section!.count > rowIndex + 1 && row.section?[rowIndex + 1] is LabelRow 271 { 272 //删除当前段落的错误信息标签 273 row.section?.remove(at: rowIndex + 1) 274 } 275 //当验证失败时 276 if !row.isValid 277 { 278 //对所有的错误信息进行遍历 279 for (index, validationMsg) in row.validationErrors.map({ $0.msg }).enumerated() 280 { 281 //创建一个标签表单行 282 let labelRow = LabelRow() 283 { 284 //设置本行的标题文字为错误信息 285 $0.title = validationMsg 286 //同时设置单元格的高度 287 $0.cell.height = { 30 } 288 } 289 //将标签行,插入到当前行的下方 290 row.section?.insert(labelRow, at: row.indexPath!.row + index + 1) 291 } 292 } 293 } 294 //添加一个网址行 295 <<< URLRow() 296 { 297 //设置本行的标题文字 298 $0.title = "URL Rule" 299 //添加验证规则,为网址格式的验证 300 $0.add(rule: RuleURL()) 301 //设置当值发生变化时进行验证 302 $0.validationOptions = .validatesOnChange 303 } 304 //设置表单的刷新动作 305 .cellUpdate 306 { 307 cell, row in 308 //当验证失败时 309 if !row.isValid 310 { 311 //设置单元格的字体颜色为红色 312 cell.titleLabel?.textColor = .red 313 } 314 } 315 //处理单元格在验证发生变化时的情况 316 .onRowValidationChanged 317 { 318 cell, row in 319 //获得当前表单行在表单中的序号 320 let rowIndex = row.indexPath!.row 321 while row.section!.count > rowIndex + 1 && row.section?[rowIndex + 1] is LabelRow 322 { 323 //删除当前段落的错误信息标签 324 row.section?.remove(at: rowIndex + 1) 325 } 326 //当验证失败时 327 if !row.isValid 328 { 329 //对所有的错误信息进行遍历 330 for (index, validationMsg) in row.validationErrors.map({ $0.msg }).enumerated() 331 { 332 //创建一个标签表单行 333 let labelRow = LabelRow() 334 { 335 //设置本行的标题文字为错误信息 336 $0.title = validationMsg 337 //同时设置单元格的高度 338 $0.cell.height = { 30 } 339 } 340 //将标签行,插入到当前行的下方 341 row.section?.insert(labelRow, at: row.indexPath!.row + index + 1) 342 } 343 } 344 } 345 //添加一个密码行 346 <<< PasswordRow("password2") 347 { 348 //设置本行的标题文字 349 $0.title = "Password" 350 //添加验证规则:长度为8~13 351 $0.add(rule: RuleMinLength(minLength: 8)) 352 $0.add(rule: RuleMaxLength(maxLength: 13)) 353 } 354 //设置表单的刷新动作 355 .cellUpdate 356 { 357 cell, row in 358 //当验证失败时 359 if !row.isValid 360 { 361 //设置单元格的字体颜色为红色 362 cell.titleLabel?.textColor = .red 363 } 364 } 365 //处理单元格在验证发生变化时的情况 366 .onRowValidationChanged 367 { 368 cell, row in 369 //获得当前表单行在表单中的序号 370 let rowIndex = row.indexPath!.row 371 while row.section!.count > rowIndex + 1 && row.section?[rowIndex + 1] is LabelRow 372 { 373 //删除当前段落的错误信息标签 374 row.section?.remove(at: rowIndex + 1) 375 } 376 //当验证失败时 377 if !row.isValid 378 { 379 //对所有的错误信息进行遍历 380 for (index, validationMsg) in row.validationErrors.map({ $0.msg }).enumerated() 381 { 382 //创建一个标签表单行 383 let labelRow = LabelRow() 384 { 385 //设置本行的标题文字为错误信息 386 $0.title = validationMsg 387 //同时设置单元格的高度 388 $0.cell.height = { 30 } 389 } 390 //将标签行,插入到当前行的下方 391 row.section?.insert(labelRow, at: row.indexPath!.row + index + 1) 392 } 393 } 394 } 395 //添加一个密码行 396 <<< PasswordRow() 397 { 398 //设置本行的标题文字 399 $0.title = "Confirm Password" 400 //添加验证规则:长度为8~13 401 $0.add(rule: RuleMinLength(minLength: 8)) 402 $0.add(rule: RuleMaxLength(maxLength: 13)) 403 } 404 //设置表单的刷新动作 405 .cellUpdate 406 { 407 cell, row in 408 //当验证失败时 409 if !row.isValid 410 { 411 //设置单元格的字体颜色为红色 412 cell.titleLabel?.textColor = .red 413 } 414 } 415 //处理单元格在验证发生变化时的情况 416 .onRowValidationChanged 417 { 418 cell, row in 419 //获得当前表单行在表单中的序号 420 let rowIndex = row.indexPath!.row 421 while row.section!.count > rowIndex + 1 && row.section?[rowIndex + 1] is LabelRow 422 { 423 //删除当前段落的错误信息标签 424 row.section?.remove(at: rowIndex + 1) 425 } 426 //当验证失败时 427 if !row.isValid 428 { 429 //对所有的错误信息进行遍历 430 for (index, validationMsg) in row.validationErrors.map({ $0.msg }).enumerated() 431 { 432 //创建一个标签表单行 433 let labelRow = LabelRow() 434 { 435 //设置本行的标题文字为错误信息 436 $0.title = validationMsg 437 //同时设置单元格的高度 438 $0.cell.height = { 30 } 439 } 440 //将标签行,插入到当前行的下方 441 row.section?.insert(labelRow, at: row.indexPath!.row + index + 1) 442 } 443 } 444 } 445 //添加一个整数行 446 <<< IntRow() 447 { 448 //设置本行的标题文字 449 $0.title = "Range Rule" 450 //添加验证规则:允许输入2`999之间的整数 451 $0.add(rule: RuleGreaterThan(min: 2)) 452 $0.add(rule: RuleSmallerThan(max: 999)) 453 } 454 //设置表单的刷新动作 455 .cellUpdate 456 { 457 cell, row in 458 //当验证失败时 459 if !row.isValid 460 { 461 //设置单元格的字体颜色为红色 462 cell.titleLabel?.textColor = .red 463 } 464 } 465 //处理单元格在验证发生变化时的情况 466 .onRowValidationChanged 467 { 468 cell, row in 469 //获得当前表单行在表单中的序号 470 let rowIndex = row.indexPath!.row 471 while row.section!.count > rowIndex + 1 && row.section?[rowIndex + 1] is LabelRow 472 { 473 //删除当前段落的错误信息标签 474 row.section?.remove(at: rowIndex + 1) 475 } 476 //当验证失败时 477 if !row.isValid 478 { 479 //对所有的错误信息进行遍历 480 for (index, validationMsg) in row.validationErrors.map({ $0.msg }).enumerated() 481 { 482 //创建一个标签表单行 483 let labelRow = LabelRow() 484 { 485 //设置本行的标题文字为错误信息 486 $0.title = validationMsg 487 //同时设置单元格的高度 488 $0.cell.height = { 30 } 489 } 490 //将标签行,插入到当前行的下方 491 row.section?.insert(labelRow, at: row.indexPath!.row + index + 1) 492 } 493 } 494 } 495 496 //添加一个新的段落 497 +++ Section() 498 //在该段落中国添加一个按钮行 499 <<< ButtonRow() 500 { 501 //设置本行的标题文字为错误信息 502 $0.title = "Tap to force form validation" 503 } 504 //当表单处于选择状态时 505 .onCellSelection 506 { 507 cell, row in 508 //强制校验表单中的所有元素 509 row.section?.form?.validate() 510 } 511 } 512 513 override func didReceiveMemoryWarning() { 514 super.didReceiveMemoryWarning() 515 // Dispose of any resources that can be recreated. 516 } 517 }