一、要实现的功能

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. 19.Remove Nth Node From End of List(List; Two-Pointers)

    Given a linked list, remove the nth node from the end of list and return its head. For example, Give ...

  2. jQuery 复制节点的元素实现添加到购物车功能

    描述: 用户点击左边div中的商品,对应商品会自动添加到右面的div中,类似电子商城中的添加到购物车功能. 主要用到了jquery中的复制节点功能,基本原理是首先获取点击的元素,然后将相应信息进行克隆 ...

  3. Django基础学习五_引入静态文件

    今天继续学习Django,今天主要掌握两个小点 一.如果为Django项目中引入静态文件 1.先要在project目录下创建static的目录,然后将jquery文件拷贝这个目录下就可以了 2.在pr ...

  4. spring property标签中的 ref属性和ref 标签有什么不同? 如下:<property name="a" ref="b" />

    spring property标签中的 ref属性和ref 标签有什么不同? 如下:<property name="a" ref="b" /> sp ...

  5. CodeForces 513A Game (水题,博弈)

    题意:两个人有n1,n2个球,然后分别最多拿出 k1,k2个球,然后扔掉,谁先拿完谁输. 析:很简单么,每人都足够聪明,就每次扔一个好了,那么,谁的球多,谁就能赢呗,如果相等,那么第一个扔的输. 代码 ...

  6. 23 DesignPatterns学习笔记:C++语言实现 --- 2.4 Composite

    23 DesignPatterns学习笔记:C++语言实现 --- 2.4 Composite 2016-07-22 (www.cnblogs.com/icmzn) 模式理解

  7. [label][IDE] Develop Node.js Project With WebStorm

    WebStorm 是一个支持 Node.js,CoffeeScript, TypeScript, Dart, Jade, Sass, LESS and Stylus 这些最新 web 开发技术的集成开 ...

  8. 查看JVM内存使用情况

    Runtime run = Runtime.getRuntime(); long max = run.maxMemory()/(1024*1024); long total = run.totalMe ...

  9. SEGGER J-Link install

    Why J-Link? In case you wonder why GNU ARM Eclipse decided to provide support to SEGGER J-Link, the ...

  10. c++中的隐藏及重载、重写与隐藏的区别

    c/c++中的隐藏  举个栗子 class A { public : void fun1(int a, int b) { cout<<"abcd"<<end ...