一、要实现的功能

1、新特性页面

1.1、是否进入新特性界面的两种情况

1)第一次安装此APP,进入新特性界面

2)不是第一次安装,但是有版本更新,进入新特性界面

1.2、具体的代码实现

      //0.版本号的key
NSString * key = @"CFBundleVersion"; //1.取出沙盒中存储的上次使用软件的版本号
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *lastVersion = [defaults stringForKey:key]; //2. 获得当前软件的版本号
NSString *currentVersion = [NSBundle mainBundle].infoDictionary[key];
//3.判读版本号
if ([currentVersion isEqualToString:lastVersion]) {//如果当前版本和沙盒中的版本一样,则不进入新特性界面
self.window.rootViewController = [[FZHTabViewController alloc]init];
} else { // 如果不一样,则进入新特性界面
self.window.rootViewController = fzhNFVC;
// 更新当前版本到沙盒一遍下次使用
[defaults setObject:currentVersion forKey:key];
[defaults synchronize];
}

2、登录注册页面

2.1、登录界面的手机号判断

1)现在的APP大部分都会使用到手机号注册这一功能,有了这个功能就会有判断手机号有效性这一需求,如果我们不判断手机号的有效性的话既会降低用户体验又会丧失掉有用的用户信息。

2)实现思路:创建一个字符串的分类来判断。

2.1.1、具体代码实现

 + (BOOL)validatePhone:(NSString *)phone
{
/**
* 手机号码
* 移动:134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
* 联通:130,131,132,152,155,156,185,186
* 电信:133,1349,153,180,189
*/
NSString * MOBILE = @"^1(3[0-9]|5[0-35-9]|8[025-9])\\d{8}$";
/**
10 * 中国移动:China Mobile
11 * 134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
12 */
NSString * CM = @"^1(34[0-8]|(3[5-9]|5[017-9]|8[278])\\d)\\d{7}$";
/**
15 * 中国联通:China Unicom
16 * 130,131,132,152,155,156,185,186
17 */
NSString * CU = @"^1(3[0-2]|5[256]|8[56])\\d{8}$";
/**
20 * 中国电信:China Telecom
21 * 133,1349,153,180,189
22 */
NSString * CT = @"^1((33|53|8[09])[0-9]|349)\\d{7}$";
/**
25 * 大陆地区固话及小灵通
26 * 区号:010,020,021,022,023,024,025,027,028,029
27 * 号码:七位或八位
28 */
// NSString * PHS = @"^0(10|2[0-5789]|\\d{3})\\d{7,8}$"; NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBILE];
NSPredicate *regextestcm = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CM];
NSPredicate *regextestcu = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CU];
NSPredicate *regextestct = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CT]; if (([regextestmobile evaluateWithObject:phone] == YES)
|| ([regextestcm evaluateWithObject:phone] == YES)
|| ([regextestct evaluateWithObject:phone] == YES)
|| ([regextestcu evaluateWithObject:phone] == YES))
{
return YES;
}
else
{
return NO;
}

2.2、密码字符位数的限制

1)实现思路:如果大于6位,则在textfiled的代理方法里面截取字符串的前六位赋值给该textfiled,如果小于六位提示密码位数不符。

2.2.1、具体代码实现

1)大于6位

 #pragma mark - #pragma mark- UITextFieldDelegate
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
range.location = ;
range.length = ; if (textField.text.length > ) {
NSString * subString = [self.password.text substringWithRange:range];
self.password.text = subString;
}
return YES;
}

2)小于6位则弹出提示框

 [MBProgressHUD showError:@"手机号码不正确或密码位数不对"];

2.3、设置键盘类型

1)因为是手机号注册,所以当用户点击textfiled的时候键盘弹出的格式应该是数字键盘,这样就省去了用户改变键盘类型的操作,提高了用户体验。

2.3.1实现代码

 self.account.keyboardType = UIKeyboardTypeNumberPad;

2.4、本地用户信息的存储

1)数据持久化存储一共有四种方法:归档、plist、SQLite、CoreData。

2)我采用的是归档的方法归档,因为可以存储自己定义的数据类型而且比较简单。

2.4.1、实现思路

1)创建自己的用户模型

2)将数据以模型的方式存储在沙盒中

2.4.2、具体的代码实现

1)数据模型的.h文件

 //账号密码
@property (nonatomic,strong)NSString * user_account;
@property (nonatomic,strong)NSString * user_password; +(instancetype)accountWithDict:(NSDictionary *)dict;
-(instancetype)initWithDict:(NSDictionary *)dict;

2)数据模型的.m文件

 +(instancetype)accountWithDict:(NSDictionary *)dict
{
return [[self alloc]initWithDict:dict];
}
-(instancetype)initWithDict:(NSDictionary *)dict
{
if (self = [super init]) {
[self setValuesForKeysWithDictionary:dict];
}
return self;
}
/**
* 从文件中解析对象的时候调
*/
- (id)initWithCoder:(NSCoder *)decoder
{
if (self = [super init]) {
self.user_account = [decoder decodeObjectForKey:@"user_account"];
self.user_password = [decoder decodeObjectForKey:@"user_password"];
}
return self;
} /**
* 将对象写入文件的时候调用
*/
- (void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:self.user_account forKey:@"user_account"];
[encoder encodeObject:self.user_password forKey:@"user_password"];
}

3)存储模型的代码

                 //1.存储用户信息
NSString * filepath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"account.data"];
NSMutableDictionary * dict = [NSMutableDictionary dictionary]; dict[@"user_account"] = self.account.text;
dict[@"user_password"] = self.password.text;
FZHAccountModel * account = [[FZHAccountModel alloc]initWithDict:dict];
[NSKeyedArchiver archiveRootObject:account toFile:filepath];

4)调取模型数据的代码

 NSString * filepath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"account.data"];
FZHAccountModel *account = [NSKeyedUnarchiver unarchiveObjectWithFile:filepath];

2.5、界面间反向传值

2.5.1、需求分析

当用户在注册界面或者登陆界面输入完信息之后当跳转到上一页面时,应该讲用户账号传递过来,不用用户再次输入账号,以此来提高用户体验。

2.5.2、实现思路

1)代理-协议,自己写一个协议来传递信息

2)block传值

2.5.3、具体代码实现(block),详细讲解:http://www.cnblogs.com/fengzhihao/p/5200527.html

1)定义block

@property (nonatomic,copy)void (^phoneBlock)(NSString * phoneNumber);

2)实现block

//block反向传值
if (self.phoneBlock) {
self.phoneBlock(self.account.text);
}

3)调用block

  FZHLoginViewController * loginVC = [[FZHLoginViewController alloc]init];
loginVC.phoneBlock = ^ (NSString * phoneNumber){
NSLog(@"%@",phoneNumber);
[self.toLoginBtn setTitle:phoneNumber forState:UIControlStateNormal]; };

二、总结

1、键盘类型具体样式

UIKeyboardTypeDefault:

UIKeyboardTypeASCIICapable:

UIKeyboardTypeNumbersAndPunctuation:

UIKeyboardTypeURL:

UIKeyboardTypeNumberPad:

UIKeyboardTypePhonePad:

UIKeyboardTypeNamePhonePad:

UIKeyboardTypeEmailAddress:

UIKeyboardTypeDecimalPad:

UIKeyboardTypeTwitter:

UIKeyboardTypeWebSearch:

UIKeyboardTypeAlphabet:

三、参考博客

1、键盘类型:http://blog.csdn.net/crazyzhang1990/article/details/39965931

四、demo下载地址

https://github.com/fengzhihao123/FZHDota2

Dota2App--第三天的更多相关文章

  1. 常用 Gulp 插件汇总 —— 基于 Gulp 的前端集成解决方案(三)

    前两篇文章讨论了 Gulp 的安装部署及基本概念,借助于 Gulp 强大的 插件生态 可以完成很多常见的和不常见的任务.本文主要汇总常用的 Gulp 插件及其基本使用,需要读者对 Gulp 有一个基本 ...

  2. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  3. Jquery的点击事件,三句代码完成全选事件

    先来看一下Js和Jquery的点击事件 举两个简单的例子 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&q ...

  4. node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理

    一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...

  5. 简谈百度坐标反转至WGS84的三种思路

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 基于百度地图进行数据展示是目前项目中常见场景,但是因为百度地图 ...

  6. 一起学 Java(三) 集合框架、数据结构、泛型

    一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个 ...

  7. 谈谈一些有趣的CSS题目(三)-- 层叠顺序与堆栈上下文知多少

    开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...

  8. 如何一步一步用DDD设计一个电商网站(三)—— 初涉核心域

    一.前言 结合我们本次系列的第一篇博文中提到的上下文映射图(传送门:如何一步一步用DDD设计一个电商网站(一)—— 先理解核心概念),得知我们这个电商网站的核心域就是销售子域.因为电子商务是以信息网络 ...

  9. 测试一下StringBuffer和StringBuilder及字面常量拼接三种字符串的效率

    之前一篇里写过字符串常用类的三种方式<java中的字符串相关知识整理>,只不过这个只是分析并不知道他们之间会有多大的区别,或者所谓的StringBuffer能提升多少拼接效率呢?为此写个简 ...

  10. 从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn)

    从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://w ...

随机推荐

  1. gradle 构建测试

    以后决不能再犯此类低级错误

  2. springcloud工程构建过程

    1.概述 2.zookeeper与eureka在CAP理论中的区别 (电商时,应当保证高可用,即最好选用AP) eureka遵守AP zookeeper遵守CP eureka集群,不区分主从节点 zo ...

  3. How to setup Laravel Homestead in Windows

    How to setup Laravel Homestead in Windows by JBorbón  17. March 2017   PHP   8 Developing with PHP u ...

  4. Disruptor 系列(一)快速入门

    Disruptor 系列(一)快速入门 Disruptor:是一个开源的并发框架,能够在 无锁 的情况下实现网络的 Queue 并发操作,所以处理数据的能力比 Java 本身提供的并发类容器要大的多, ...

  5. java 内存 线程 类 vm分析工具

    JMeter.Jconsole.JVMStat

  6. Mysql--关于数值字段的比较问题

    今天在进行数据库查询的过程中,因为需要比较一条记录中两个字段的大小问题 select * from cyber_download_rate where measure_time between '20 ...

  7. linux每天一小步---xargs命令详解

    1 命令功能 xargs用来从标准输入中执行命令行 xargs命令用来将一些不支持管道传递参数的命令而使之支持 2 命令语法 xargs  [选项参数] commands 3 命令参数 -O 当标准输 ...

  8. [leetcode] 12. Merge Sorted Array

    这道题的无聊之处在于题目其实给了一些很奇怪的测试用例.比如他会给一些空的数组来,但是这个是不科学的,因为在C++中不允许定义一个空的列表,我们用的又不是那种糙又快的python,所以在这里我遇到了一些 ...

  9. mysql in语句在java中的使用

    做权限的时候,通过role角色中的roleid,在auth权限中查找角色对应的权限. sql语句: SELECT authName from auth where authId in (1,2,3,4 ...

  10. 【译】ASP.NET MVC 5 官方教程 - 目录

    ASP.NET MVC 5 官方教程 - 目录 [译]ASP.NET MVC 5 教程 - 1:入门 [译]ASP.NET MVC 5 教程 - 2:添加控制器 [译]ASP.NET MVC 5 教程 ...