添加PCH文件Starry.pch
在程序Build Settings 的Prefix Header 写上$(SRCROOT)/工程名称/Starry.pch
Starry.pch
#ifndef Starry_pch
#define Starry_pch
/*
常用头文件的导入
*/
#import "BaseViewController.h"
#import "AppDelegate.h"
#import "MBProgressHUD.h"
#import "UIView+NewMethods.h"
#import "NSString+NewMethods.h"
#import "UserDataBase.h"
#import "NewsDataBase.h"
#import "UIImage+Tailor.h"
#import "QRCodeGenerator.h"
#import "URLService.h"
#define App_Delegate (AppDelegate *)[UIApplication sharedApplication].delegate
/*
系统版本号
*/
#define VERSION_10_0 [UIDevice currentDevice].systemVersion.doubleValue >= 10.0
#define VERSION_9_0 [UIDevice currentDevice].systemVersion.doubleValue >= 9.0
/*
用于适配的宏
*/
#define SCR_W [UIScreen mainScreen].bounds.size.width
#define SCR_H [UIScreen mainScreen].bounds.size.height
//适配x轴的宏
#define FIT_X(w) (SCR_W / 375. *(w))
//适配Y轴的宏
#define FIT_Y(h) (SCR_H / 667. *(h))
/*
当前app版本号的宏
*/
#define VERSION_CURRENT [[NSBundle mainBundle].infoDictionary objectForKey:@"CFBundleShortVersionString"]
//持久化当前版本号的key的宏
#define NOT_FIRST_LANUCH @"NotFirstLanuch"
/*
Doucuments目录的宏
*/
#define DOCUMENT_PATH [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]
/*
注册通知
*/
//退出登录
#define LOGOUT_NOTIFICATION_NAME @"logoutNotification"
#endif /* Starry_pch */
Category
UIView+NewMethods.h
#import
@interface UIView (NewMethods)
//获取当前view所在的Controller对象
-(UIViewController *)getCurrentViewController;
//用来显示一个文本的MBProgressHUD
- (void)showTextStyleMBProgressHUDWithTitle:(NSString *)title;
//用来显示一个等待指示器的MBProgressHUD
- (void)showIdicatorMBProgressHUD;
//隐藏一个等待指示器的MBProgressHUD
- (void)hideIdicatorMBProgressHUD;
@end
UIView+NewMethods.m
#import "UIView+NewMethods.h"
@implementation UIView (NewMethods)
//获取当前view所在的Controller对象
-(UIViewController *)getCurrentViewController{
for (UIView *preView = self; preView; preView = preView.superview) {
UIResponder *next = self.nextResponder;
if ([next isKindOfClass:[UIViewController class]]) {
return (UIViewController *)next;
}
}
return nil;
}
//用来显示一个文本的MBProgressHUD
- (void)showTextStyleMBProgressHUDWithTitle:(NSString *)title{
MBProgressHUD *hud = [[MBProgressHUD alloc]initWithView:self];
hud.mode = MBProgressHUDModeText;
hud.labelText = title;
hud.removeFromSuperViewOnHide = YES;
[self addSubview:hud];
[hud show:YES];
[hud hide:YES afterDelay:2.0];
}
//用来显示一个等待指示器的MBProgressHUD
- (void)showIdicatorMBProgressHUD{
MBProgressHUD *hud = [[MBProgressHUD alloc]initWithView:self];
[self addSubview:hud];
hud.removeFromSuperViewOnHide = YES;
hud.tag = 888;
[hud show:YES];
}
//隐藏一个等待指示器的MBProgressHUD
- (void)hideIdicatorMBProgressHUD{
UIView *sub = [self viewWithTag:888];
if ([sub isMemberOfClass:[MBProgressHUD class]]) {
MBProgressHUD *hud = (MBProgressHUD *)sub;
[hud hide:YES];
hud = nil;
}
}
@end
NSString+NewMethods.h
#import
@interface NSString (NewMethods)
//判断是否是一个正确的手机号
- (BOOL)isACorrectPhoneNumber;
//判断是不是一个正确的身份证号
- (BOOL)isPresonalID;
//判断是不是正确的网址
- (BOOL)isAURLString;
#pragma mark ---- base 64
//对一个字符串进行base64编码,并且返回
- (NSString *)base64EncodeString;
//对base64编码之后的字符串解码,并且返回
- (NSString *)base64DecodeString;
#pragma mark ------- MD5、HMAC加密 ---------
- (NSString *)md5String;
//HMAC+MD5加密
- (NSString *)hmacMD5StringWithKey:(NSString *)key;
@end
NSString+NewMethods.m
#import "NSString+NewMethods.h"
#import
@implementation NSString (NewMethods)
//判断是否是一个正确的手机号
- (BOOL)isACorrectPhoneNumber{
//正则语句
NSString *regularStr = @"^((13[0-9]\\d{8})|(15[0-9]\\d{8})|(17[0-9]\\d{8})|(18[0-9]\\d{8}))";
NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regularStr];
//看是否匹配
return [pre evaluateWithObject:self];
}
//判断是不是一个正确的身份证号
- (BOOL)isPresonalID{
return NO;
}
//判断是不是正确的网址
- (BOOL)isAURLString{
if ([self hasPrefix:@"http://"] || [self hasPrefix:@"https://"]) {
return YES;
}
return NO;
}
#pragma mark ---- base 64
//对一个字符串进行base64编码,并且返回
- (NSString *)base64EncodeString{
//1.先转换为二进制数据
NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
//2对二进制数据进行base64编码,完成之后返回字符串
return [data base64EncodedStringWithOptions:0];
}
//对base64编码之后的字符串解码,并且返回
- (NSString *)base64DecodeString{
//base64之后的字符串转换为二进制数据
NSData *data = [[NSData alloc]initWithBase64EncodedString:self options:0];
//把二进制数据转换为字符串
return [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
}
#pragma mark ------- MD5、HMAC加密 ---------
/**
* 返回二进制 Bytes 流的字符串表示形式
* @param bytes 二进制 Bytes 数组
* @param length 数组长度
* @return 字符串表示形式
*/
- (NSString *)stringFromBytes:(uint8_t *)bytes length:(int)length {
NSMutableString *strM = [NSMutableString string];
for (int i = 0; i < length; i++) {
[strM appendFormat:@"%02x", bytes[i]];
}
return [strM copy];
}
// md5加密方法
- (NSString *)md5String {
const char *str = self.UTF8String;
uint8_t buffer[CC_MD5_DIGEST_LENGTH];
CC_MD5(str, (CC_LONG)strlen(str), buffer);
return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
}
// HMACMD5加密方法
- (NSString *)hmacMD5StringWithKey:(NSString *)key {
const char *keyData = key.UTF8String;
const char *strData = self.UTF8String;
uint8_t buffer[CC_MD5_DIGEST_LENGTH];
CCHmac(kCCHmacAlgMD5, keyData, strlen(keyData), strData, strlen(strData), buffer);
return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
}
@end
UIImage+Tailor.h
#import
@interface UIImage (Tailor)
//对图片按固定尺寸做裁剪
- (UIImage *)scaleToSize:(CGSize)size;
@end
UIImage+Tailor.m
#import "UIImage+Tailor.h"
@implementation UIImage (Tailor)
//等比例缩放
-(UIImage *)scaleToSize:(CGSize)size{
//获取图片原始尺寸
CGFloat width = CGImageGetWidth(self.CGImage);
CGFloat height = CGImageGetHeight(self.CGImage);
//缩放比例
float verticalRadio = size.height * 1.0 / height;
float horizontalRadio = size.width * 1.0 / width;
float radio = 1;
if (verticalRadio > 1 && horizontalRadio > 1) {
radio = verticalRadio > horizontalRadio ? horizontalRadio : verticalRadio;
}
else
{
radio = verticalRadio < horizontalRadio ? verticalRadio : horizontalRadio;
}
width = width * radio;
height = height * radio;
int xPos = (size.width - width) / 2;
int yPos = (size.height -height) / 2;
//创建一个bitmap的context
//并把它设置成为当前正在使用的context
UIGraphicsBeginImageContext(size);
//绘制改变大小的图片
[self drawInRect:CGRectMake(xPos, yPos, width, height)];
//从当前context中创建一个改变大小后的图片
UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
//使当前的context出堆栈
UIGraphicsEndImageContext();
//返回新的改变大小后的图片
return scaledImage;
}
@end
User.h
#import
@interface User : NSObject//采用归档协议
@property (nonatomic,assign)int ID;
@property (nonatomic,strong)NSString *phone;
@property (nonatomic,strong)NSString *password;
@property (nonatomic,strong)NSString *name;
@property (nonatomic,assign)int age;
@property (nonatomic,strong)NSString *headImg;
@property (nonatomic,strong)NSString *address;
@end
User.m
#import "User.h"
@implementation User
// 归档方法,将所有属性编程二进制数据
-(void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeInt:self.ID forKey:@"ID"];
[aCoder encodeObject:self.phone forKey:@"phone"];
[aCoder encodeObject:self.password forKey:@"password"];
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeObject:self.address forKey:@"address"];
[aCoder encodeObject:self.headImg forKey:@"headImg"];
[aCoder encodeInt:self.age forKey:@"age"];
}
// 反归档方法,将二进制数据转换为属性数据
-(instancetype)initWithCoder:(NSCoder *)aDecoder{
self = [super init];
if (self) {
self.ID = [aDecoder decodeIntForKey:@"ID"];
self.phone = [aDecoder decodeObjectForKey:@"phone"];
self.password = [aDecoder decodeObjectForKey:@"password"];
self.name = [aDecoder decodeObjectForKey:@"name"];
self.address = [aDecoder decodeObjectForKey:@"address"];
self.headImg = [aDecoder decodeObjectForKey:@"headImg"];
self.age = [aDecoder decodeIntForKey:@"age"];
}
return self;
}
@end
UserDataBase.h 业务
#import
#import "User.h"
@interface UserDataBase : NSObject
//类方法,用于外部类获取该单例类对象
+ (instancetype)sharedDataBase;
//注册添加新用户
- (BOOL)addNewAccount:(NSString *)phone password:(NSString *)pwd;
//登录
- (BOOL)loginWithAccount:(NSString *)phone password:(NSString *)pwd;
//更新
- (BOOL)updateUser:(User *)newUser;
//退出登录
- (BOOL)logOut;
//判断是否有人登录
- (BOOL)userHadLogin;
//获取当前人登录信息
- (User *)getCurrentLoginUser;
@end
UserDataBase.m
#import "UserDataBase.h"
#import "FMDB.h"
#define TABLE_CREAT @"CREATE TABLE user (id INTEGER PRIMARY KEY AUTOINCREMENT, phone TEXT UNIQUE, password TEXT, name TEXT, headImg TEXT, address TEXT, age INTEGER)"
//插入数据的SQL语句
#define INSER_USER @"INSERT INTO user (phone,password) VALUES (%@,%@)"
//查找用户语句
#define SEARCH_USER @"SELECT * FROM user WHERE phone = %@ AND password = %@"
//更新用户数据
#define UPDATE_USER @"UPDATE user SET password = %@ , name = %@, headImg = %@,address = %@,age = %d WHERE id = %d"
//表示持久化登录用户的key
#define SAVED_LOGIN_USER @"currentLoginUserSaved"
//HAMC加密的key
#define HMAC_KEY @"65_num$@*.76_dd"
static UserDataBase *_defaultUserDB = nil;
@interface UserDataBase ()
@property (nonatomic,strong)FMDatabase *fmDB;
@end
@implementation UserDataBase
#pragma mark - FMDataBase
- (FMDatabase *)fmDB{
if (!_fmDB) {
//文件路径
NSString *filePath = [DOCUMENT_PATH stringByAppendingPathComponent:@"starrysky.db"];
NSLog(@"数据库路径%@",filePath);
_fmDB = [FMDatabase databaseWithPath:filePath];
}
return _fmDB;
}
//初始化数据表
- (BOOL)initTable{
[self.fmDB open];
BOOL res = [self.fmDB executeUpdate:TABLE_CREAT];
[self.fmDB close];
return res;
}
#pragma mark - init重写
- (instancetype)init{
self = [super init];
if (self) {
[self initTable];
}
return self;
}
#pragma mark -单例实现方法
//实例对外的类方法
+(instancetype)sharedDataBase{
if (_defaultUserDB == nil) {
_defaultUserDB = [[UserDataBase alloc]init];
}
return _defaultUserDB;
}
//重写allocWithZone方法.防止使用alloc生成新对象
+(instancetype)allocWithZone:(struct _NSZone *)zone{
if (_defaultUserDB == nil) {
_defaultUserDB = [super allocWithZone:zone];
}
return _defaultUserDB;
}
- (id)copy{
return self;
}
- (id)mutableCopy{
return self;
}
#pragma mark--私有方法
#pragma mark -对外接口实现
//注册,添加新用户
- (BOOL)addNewAccount:(NSString *)phone password:(NSString *)pwd{
[self.fmDB open];
BOOL res = [self.fmDB executeUpdateWithFormat:INSER_USER,phone,[pwd hmacMD5StringWithKey:HMAC_KEY]];
[self.fmDB close];
return res;
}
//登录
- (BOOL)loginWithAccount:(NSString *)phone password:(NSString *)pwd{
//判断数据库是否打开成功
if (![self.fmDB open]) {
[self.fmDB close];
return NO;
}
//数据库打开成功,去查找用户
FMResultSet *res = [self.fmDB executeQueryWithFormat:SEARCH_USER,phone,[pwd hmacMD5StringWithKey:HMAC_KEY]];
User *u = nil;
while ([res next]) {
u = [[User alloc]init];
u.ID = [res intForColumn:@"id"];
u.phone = [res stringForColumn:@"phone"];
u.password = [res stringForColumn:@"password"];
u.name = [res stringForColumn:@"name"];
u.headImg = [res stringForColumn:@"headImg"];
u.age = [res intForColumn:@"age"];
u.address = [res stringForColumn:@"address"];
}
if (u == nil) {
[self.fmDB close];
return NO;//登录失败
}
//将登录人信息持久化
//使用归档类将自定义的对象数据转换为二进制数据
NSData *uData = [NSKeyedArchiver archivedDataWithRootObject:u];
[[NSUserDefaults standardUserDefaults]setObject:uData forKey:SAVED_LOGIN_USER];
[[NSUserDefaults standardUserDefaults]synchronize];
[self.fmDB close];
return YES;
return NO;
}
//更新
- (BOOL)updateUser:(User *)newUser{
/*
1将数据库的数据更新
*/
if (![self.fmDB open]) {
[self.fmDB close];
return NO;
}
//执行sql语句
BOOL success = [self.fmDB executeUpdateWithFormat:UPDATE_USER,newUser.password,newUser.name,newUser.headImg,newUser.address,newUser.age,newUser.ID];
//执行sql失败
if(!success){
[self.fmDB close];
return NO;
}
/*
2将持久化的数据更新
*/
[[NSUserDefaults standardUserDefaults]setObject:[NSKeyedArchiver archivedDataWithRootObject:newUser] forKey:SAVED_LOGIN_USER];
[self.fmDB close];
return [[NSUserDefaults standardUserDefaults]synchronize];
}
//退出登录
- (BOOL)logOut{
//将持久化的代理人数据删除
[[NSUserDefaults standardUserDefaults]removeObjectForKey:SAVED_LOGIN_USER];
return [[NSUserDefaults standardUserDefaults]synchronize];
}
//判断是否有人登录
- (BOOL)userHadLogin{
id obj = [[NSUserDefaults standardUserDefaults]objectForKey:SAVED_LOGIN_USER];
return obj != nil;
}
//获取当前人登录信息
- (User *)getCurrentLoginUser{
//把持久化的登录人信息获取
NSData *uData = [[NSUserDefaults standardUserDefaults]objectForKey:SAVED_LOGIN_USER];
//用反序列化类将二进制数据转换为User对象
User *u = [NSKeyedUnarchiver unarchiveObjectWithData:uData];
return u;
}
@end
LoginViewController.h 登录
#import
@interface LoginViewController : UIViewController
@end
LoginViewController.m
#import "LoginViewController.h"
#import "LoginView.h"
#import "RegisterViewController.h"
#import "UserDataBase.h"
@interface LoginViewController ()
@property (nonatomic,strong)LoginView *logView;
@property (nonatomic,strong)RegisterViewController *registerVC;
@end
@implementation LoginViewController
#pragma mark -LoginViewDelegate 自定义代理
//view中关闭按钮触发
- (void)shutViewAndBack{
[self dismissViewControllerAnimated:YES completion:nil];
}
//执行登录
- (void)handleLoginEventWithAccount:(NSString *)acc password:(NSString *)pwd{
NSLog(@"%@,%@",acc,pwd);
BOOL success = [[UserDataBase sharedDataBase]loginWithAccount:acc password:pwd];
if (success) {
[self dismissViewControllerAnimated:YES completion:nil];
}else{
[self.logView showTextStyleMBProgressHUDWithTitle:@"登录失败"];
}
}
//执行注册
- (void)handleResgisterAndPresent{
[self presentViewController:self.registerVC animated:YES completion:nil];
}
//执行第三方登录
- (void)handleThirdLoginWithType:(ThirdLoginType)type{
switch (type) {
case ThirdLoginType_WeiBo:
NSLog(@"微博第三方登录");
break;
case ThirdLoginType_QQ:
NSLog(@"QQ第三方登录");
break;
case ThirdLoginType_WeChat:
NSLog(@"微信第三方登录");
break;
default:
break;
}
}
#pragma mark -
- (LoginView *)logView{
if (!_logView) {
_logView = [[LoginView alloc]initWithFrame:self.view.frame];
_logView.delegate = self;
}
return _logView;
}
-(void)loadView{
[super loadView];
self.view = self.logView;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.registerVC = [[RegisterViewController alloc]init];
}
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.logView clearAllTextFieldContent];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
LoginView.h
#import
//自定义枚举类型,表示第三方登录的方式
typedef enum {
ThirdLoginType_WeiBo = 300,
ThirdLoginType_QQ,
ThirdLoginType_WeChat
}ThirdLoginType;
//协议
@protocol LoginViewDelegate
//关闭视图控制器
- (void)shutViewAndBack;
//登录按钮触发,执行登录
- (void)handleLoginEventWithAccount:(NSString *)acc password:(NSString *)pwd;
//注册按钮触发,进入注册视图
- (void)handleResgisterAndPresent;
//第三方登录,执行第三方代码
- (void)handleThirdLoginWithType:(ThirdLoginType)type;
@end
@interface LoginView : UIView
@property (nonatomic,assign)id delegate;
//清空文本框的内容
- (void)clearAllTextFieldContent;
@end
LoginView.m
#import "LoginView.h"
@interface LoginView ()
@property (nonatomic,strong)UITextField *accountTF;
@property (nonatomic,strong)UITextField *pwdTF;
@property (nonatomic,strong)UIButton *loginBtn;
@property (nonatomic,strong)UIButton *registerBtn;
@property (nonatomic,strong)UIButton *shutBtn;
@property (nonatomic,strong)UIView *thirdLoginView;
@end
@implementation LoginView
#pragma mark-UITextFieldDelegate
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
//获取当前文本内容
NSString *current = [textField.text stringByReplacingCharactersInRange:range withString:string];
if (textField.tag == 101) {
//账号
return current.length <= 11;
}else{
//密码
return current.length <= 16;
}
return YES;
}
#pragma mark - 控件实例化
//关闭按钮
- (UIButton *)shutBtn{
if (!_shutBtn) {
_shutBtn = [UIButton buttonWithType:UIButtonTypeCustom];
_shutBtn.frame = CGRectMake(FIT_X(15), FIT_Y(20), 30, 30);
[_shutBtn setImage:[UIImage imageNamed:@"navigationItem_back"] forState:UIControlStateNormal];
[_shutBtn addTarget:self action:@selector(shutBtnHandle:) forControlEvents:UIControlEventTouchUpInside];
}
return _shutBtn;
}
#pragma mark - 控件触发方法
//关闭按钮触发
- (void)shutBtnHandle:(id)sender{
[self.delegate shutViewAndBack];
}
//登录按钮触发
- (void)loginBtnHandle:(id)sender{
//判断账号密码不为空
if (self.accountTF.text.length == 0 || self.pwdTF.text.length == 0) {
[self showTextStyleMBProgressHUDWithTitle:@"账号密码不可为空"];
return;
}
id obj = self.delegate;
if ([obj respondsToSelector:@selector(handleLoginEventWithAccount:password:)]) {
[self.delegate handleLoginEventWithAccount:self.accountTF.text password:self.pwdTF.text];
}
}
//注册按钮触发
- (void)registerBtnHandle:(id)sender{
[self.delegate handleResgisterAndPresent];
}
//第三方登录触发
- (void)thirdLoginBtnHandle:(UIButton *)sender{
[self.delegate handleThirdLoginWithType:(ThirdLoginType)sender.tag];
}
//账号文本输入
- (UITextField *)accountTF{
if (!_accountTF) {
_accountTF = [[UITextField alloc]initWithFrame:CGRectMake(FIT_X(15), FIT_Y(20)+30+FIT_Y(100),SCR_W - FIT_X(30), FIT_Y(60))];
_accountTF.background = [UIImage imageNamed:@"登录_03"];
_accountTF.delegate = self;
_accountTF.tag = 101;
_accountTF.attributedPlaceholder = [[NSAttributedString alloc]initWithString:@"请输入账号" attributes:@{NSForegroundColorAttributeName:[UIColor whiteColor],NSFontAttributeName:[UIFont systemFontOfSize:18.0]}];
_accountTF.textAlignment = NSTextAlignmentCenter;
_accountTF.clearButtonMode = UITextFieldViewModeWhileEditing;
_accountTF.clearsOnBeginEditing = YES;
_accountTF.keyboardType = UIKeyboardTypePhonePad;
_accountTF.textColor = [UIColor whiteColor];
[_accountTF setValue:[UIColor grayColor] forKeyPath:@"_clearButton.backgroundColor"];
}
return _accountTF;
}
//密码输入
- (UITextField *)pwdTF{
if (!_pwdTF) {
_pwdTF = [[UITextField alloc]initWithFrame:CGRectMake(FIT_X(15), FIT_Y(20)+30+FIT_Y(180),SCR_W - FIT_X(30), FIT_Y(60))];
_pwdTF.background = [UIImage imageNamed:@"登录_07"];
_pwdTF.delegate = self;
_pwdTF.tag = 102;
_pwdTF.attributedPlaceholder = [[NSAttributedString alloc]initWithString:@"请输入密码" attributes:@{NSForegroundColorAttributeName:[UIColor whiteColor],NSFontAttributeName:[UIFont systemFontOfSize:18.0]}];
_pwdTF.textAlignment = NSTextAlignmentCenter;
_pwdTF.clearButtonMode = UITextFieldViewModeWhileEditing;
_pwdTF.clearsOnBeginEditing = YES;
_pwdTF.keyboardType = UIKeyboardTypeDefault;
_pwdTF.secureTextEntry = YES;
_pwdTF.textColor = [UIColor whiteColor];
[_pwdTF setValue:[UIColor whiteColor] forKeyPath:@"_clearButton.backgroundColor"];
}
return _pwdTF;
}
//登录按钮
- (UIButton *)loginBtn{
if (!_loginBtn) {
_loginBtn = [UIButton buttonWithType:UIButtonTypeCustom];
_loginBtn.frame = CGRectMake(FIT_X(30), self.pwdTF.frame.origin.y + self.pwdTF.frame.size.height + FIT_Y(30), SCR_W - FIT_X(60), FIT_Y(60));
[_loginBtn setBackgroundImage:[UIImage imageNamed:@"登录_11"] forState:UIControlStateNormal];
[_loginBtn setTitle:@"登 录" forState:UIControlStateNormal];
_loginBtn.titleLabel.font = [UIFont systemFontOfSize:20.0];
[_loginBtn addTarget:self action:@selector(loginBtnHandle:) forControlEvents:UIControlEventTouchUpInside];
}
return _loginBtn;
}
//注册按钮
- (UIButton *)registerBtn{
if (!_registerBtn) {
_registerBtn = [UIButton buttonWithType:UIButtonTypeSystem];
_registerBtn.frame = CGRectMake(0, 0, FIT_X(100), FIT_Y(20));
_registerBtn.center = CGPointMake(SCR_W / 2, SCR_H - FIT_Y(150));
[_registerBtn setTitle:@"- 注册 -" forState:UIControlStateNormal];
[_registerBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[_registerBtn addTarget:self action:@selector(registerBtnHandle:) forControlEvents:UIControlEventTouchUpInside];
}
return _registerBtn;
}
//第三方登录视图
- (UIView *)thirdLoginView{
if (!_thirdLoginView) {
_thirdLoginView = [[UIView alloc]initWithFrame:CGRectMake(SCR_W / 2 - FIT_X(70), self.registerBtn.frame.origin.y + self.registerBtn.frame.size.height + FIT_Y(10), SCR_W, FIT_Y(40))];
NSArray *imgArr = @[@"登录_15",@"登录_17",@"登录_19"];
for (int i = 0; i *)touches withEvent:(UIEvent *)event{
[super touchesBegan:touches withEvent:event];
[self endEditing:YES];
}
#pragma mark - initWithFrame
//清空文本框的内容
- (void)clearAllTextFieldContent{
self.accountTF.text = @"";
self.pwdTF.text = @"";
}
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
UIImageView *backView = [[UIImageView alloc]initWithFrame:self.frame];
backView.image = [UIImage imageNamed:@"登录"];
[self addSubview:backView];
[self addSubview:self.shutBtn];
[self addSubview:self.accountTF];
[self addSubview:self.pwdTF];
[self addSubview:self.loginBtn];
[self addSubview:self.registerBtn];
[self addSubview:self.thirdLoginView];
}
return self;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
@end
RegisterViewController.h 注册
#import
@interface RegisterViewController : UIViewController
@end
RegisterViewController.m
#import "RegisterViewController.h"
#import "RegisterView.h"
#import
#import "UserDataBase.h"
@interface RegisterViewController ()
@property (nonatomic,strong)RegisterView *regView;
@end
@implementation RegisterViewController
#pragma mark ------ RegisterViewDelegate ------
//请求短信验证码
- (void)requestVertifyCodeWithPhoneNumber:(NSString *)phone{
[SMSSDK getVerificationCodeByMethod:SMSGetCodeMethodSMS phoneNumber:phone zone:@"86" result:^(NSError *error) {
if (!error)
{
// 请求成功
NSLog(@"成功");
}
else
{
// error
NSLog(@"失败");
[self.regView showTextStyleMBProgressHUDWithTitle:@"获取验证码失败"];
[self.regView getCodeAgain];
}
}];
}
//注册
- (void)handleRegisterWithAccount:(NSString *)phone password:(NSString *)pwd inputCode:(NSString *)code{
#if 0 //如果是1,表示不进行短信验证,直接注册,改为0表示上线的真实状态
BOOL success = [[UserDataBase sharedDataBase]addNewAccount:phone password:pwd];
if (!success) {
[self.regView showTextStyleMBProgressHUDWithTitle:@"用户已存在,注册失败"];
}
else{
[self.regView showTextStyleMBProgressHUDWithTitle:@"注册成功"];
[self performSelector:@selector(hideSelf) withObject:nil afterDelay:2.0];
}
#else
//显示等待指示器
[self.regView showIdicatorMBProgressHUD];
[SMSSDK commitVerificationCode:code phoneNumber:phone zone:@"86" result:^(NSError *error) {
//隐藏等待指示器
[self.regView hideIdicatorMBProgressHUD];
if (!error)
{
// 验证成功
NSLog(@"验证成功");
BOOL success = [[UserDataBase sharedDataBase]addNewAccount:phone password:pwd];
if (!success) {
[self.regView showTextStyleMBProgressHUDWithTitle:@"用户已存在,注册失败"];
}
else{
[self.regView showTextStyleMBProgressHUDWithTitle:@"注册成功"];
[self performSelector:@selector(hideSelf) withObject:nil afterDelay:2.0];
}
}
else
{
// error
[self.regView showTextStyleMBProgressHUDWithTitle:@"验证码错误"];
}
}];
#endif
}
- (void)hideSelf{
[self dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark ------ loadView------
-(void)loadView{
[super loadView];
self.regView = [[RegisterView alloc]initWithFrame:self.view.frame];
self.regView.delegate = self;
self.view = self.regView;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
RegisterView.h
#import
//协议
@protocol RegisterViewDelegate
//请求短信验证码
- (void)requestVertifyCodeWithPhoneNumber:(NSString *)phone;
//执行注册
- (void)handleRegisterWithAccount:(NSString *)phone password:(NSString *)pwd inputCode:(NSString *)code;
@end
@interface RegisterView : UIView
@property (nonatomic,weak)iddelegate;
//重新获取验证码
- (void)getCodeAgain;
@end
RegisterView.m
#import "RegisterView.h"
#define FONT_SIZE 20.
@interface RegisterView ()
{
int _totalTime;//倒计时总时间
}
@property (nonatomic,strong)UIButton *shutBtn;
@property (nonatomic,strong)UITextField *phoneTF;
@property (nonatomic,strong)UIButton *getVertifyCodeBtn;
@property (nonatomic,strong)UITextField *vertifyCodeTF;
@property (nonatomic,strong)UITextField *pwdTF;
@property (nonatomic,strong)UITextField *vertifyPwdTF;
@property (nonatomic,strong)UIButton *registerBtn;
@property (nonatomic,strong)NSTimer *timer;
@end
@implementation RegisterView
#pragma mark - 对外接口
//重新获取验证码
- (void)getCodeAgain{
_totalTime = 1;
}
#pragma mark - 控件触发事件
//关闭按钮触发
- (void)shutBtnHandle:(id)sender{
//寻找当前view所在的viewController
UIViewController *vc = [self getCurrentViewController];
[vc dismissViewControllerAnimated:YES completion:nil];
}
//获取验证码按钮触发
- (void)getVertifyCodeBtnHandle:(UIButton *)sender{
/*
1视图的输入判断
*/
if (self.phoneTF.text.length == 0)
{
[self showTextStyleMBProgressHUDWithTitle:@"手机号不可为空"];
return;
}
if (![self.phoneTF.text isACorrectPhoneNumber]) {
[self showTextStyleMBProgressHUDWithTitle:@"请输入正确的手机号"];
return;
}
/*
2改变UI样子
*/
//让按钮处于不可用状态
sender.userInteractionEnabled = NO;
//改变按钮的透明度
sender.alpha = 0.8;
/*
3倒计时
*/
//设置倒计时的初始总时间
_totalTime = 60;
if (VERSION_10_0) {
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
NSString *s = [NSString stringWithFormat:@"%02ds",_totalTime--];
[self.getVertifyCodeBtn setTitle:s forState:UIControlStateNormal];
if (_totalTime == 0) {
self.getVertifyCodeBtn.userInteractionEnabled = YES;
//改变按钮的透明度
sender.alpha = 1.0;
[self.getVertifyCodeBtn setTitle:@"再次获取" forState:UIControlStateNormal];
[self.timer invalidate];
self.timer = nil;
}
}];
}else{
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerHandle:) userInfo:nil repeats:YES];
}
/*
4请求短信验证码
*/
[self.delegate requestVertifyCodeWithPhoneNumber:self.phoneTF.text];
}
//定时器9.0触发
- (void)timerHandle:(NSTimer *)t{
NSString *s = [NSString stringWithFormat:@"%02ds",_totalTime--];
[self.getVertifyCodeBtn setTitle:s forState:UIControlStateNormal];
if (_totalTime == 0) {
self.getVertifyCodeBtn.userInteractionEnabled = YES;
//改变按钮的透明度
self.getVertifyCodeBtn.alpha = 1.0;
[self.getVertifyCodeBtn setTitle:@"再次获取" forState:UIControlStateNormal];
[self.timer invalidate];
self.timer = nil;
}
}
//注册按钮触发
- (void)registerBtnHandle:(id)sender{
//为空判断
if (self.phoneTF.text.length == 0 || self.vertifyCodeTF.text.length == 0 || self.pwdTF.text.length == 0 || self.vertifyPwdTF.text.length == 0) {
[self showTextStyleMBProgressHUDWithTitle:@"信息不可为空"];
return;
}
//如果不是正确的手机号
if (![self.phoneTF.text isACorrectPhoneNumber]) {
[self showTextStyleMBProgressHUDWithTitle:@"手机号错误"];
return;
}
//密码和验证密码是否相同
if (![self.pwdTF.text isEqualToString:self.vertifyPwdTF.text]) {
[self showTextStyleMBProgressHUDWithTitle:@"输入密码不一致"];
return;
}
//执行注册
[self.delegate handleRegisterWithAccount:self.phoneTF.text password:self.pwdTF.text inputCode:self.vertifyCodeTF.text];
}
#pragma mark - 控件实例化
//关闭按钮
- (UIButton *)shutBtn{
if (!_shutBtn) {
_shutBtn = [UIButton buttonWithType:UIButtonTypeCustom];
_shutBtn.frame = CGRectMake(FIT_X(15), FIT_Y(20), 30, 30);
[_shutBtn setImage:[UIImage imageNamed:@"navigationItem_back"] forState:UIControlStateNormal];
[_shutBtn addTarget:self action:@selector(shutBtnHandle:) forControlEvents:UIControlEventTouchUpInside];
}
return _shutBtn;
}
//构建文本输入框的方法
- (UITextField *)createTFWithFrame:(CGRect)frame placeholder:(NSString *)content tag:(NSUInteger)tag{
UITextField *tf = [[UITextField alloc]initWithFrame:frame];
tf.attributedPlaceholder = [[NSAttributedString alloc]initWithString:content attributes:@{NSForegroundColorAttributeName:[UIColor whiteColor],NSFontAttributeName:[UIFont systemFontOfSize:20.0]}];
tf.font = [UIFont systemFontOfSize:20.0];
tf.textColor = [UIColor whiteColor];
tf.textAlignment = NSTextAlignmentCenter;
tf.delegate = self;
tf.layer.borderColor = [[UIColor orangeColor]CGColor];
tf.layer.borderWidth = 1.0;
tf.tag = tag;
return tf;
}
//手机号输入文本框
- (UITextField *)phoneTF{
if (!_phoneTF) {
_phoneTF = [self createTFWithFrame:CGRectMake(FIT_X(20), FIT_Y(20) + 30 + FIT_Y(50),FIT_X(200), FIT_Y(60)) placeholder:@"请输入手机号" tag:201];
_phoneTF.keyboardType = UIKeyboardTypePhonePad;
}
return _phoneTF;
}
//获取短信验证码按钮
- (UIButton *)getVertifyCodeBtn{
if (!_getVertifyCodeBtn) {
_getVertifyCodeBtn = [UIButton buttonWithType:UIButtonTypeCustom];
_getVertifyCodeBtn.frame = CGRectMake(self.phoneTF.frame.origin.x + self.phoneTF.frame.size.width + FIT_X(10), self.phoneTF.frame.origin.y + FIT_Y(10), FIT_X(120), FIT_Y(40));
[_getVertifyCodeBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[_getVertifyCodeBtn setTitle:@"获取验证码" forState:UIControlStateNormal];
_getVertifyCodeBtn.titleLabel.font = [UIFont systemFontOfSize:FONT_SIZE];
_getVertifyCodeBtn.backgroundColor = [UIColor orangeColor];
[_getVertifyCodeBtn addTarget:self action:@selector(getVertifyCodeBtnHandle:) forControlEvents:UIControlEventTouchUpInside];
}
return _getVertifyCodeBtn;
}
//验证码输入框
- (UITextField *)vertifyCodeTF{
if (!_vertifyCodeTF) {
_vertifyCodeTF = [self createTFWithFrame:CGRectMake(FIT_X(20), self.phoneTF.frame.origin.y+self.phoneTF.frame.size.height + FIT_Y(10), FIT_X(160), FIT_Y(60)) placeholder:@"请输入验证码" tag:202];
_vertifyCodeTF.keyboardType = UIKeyboardTypePhonePad;
}
return _vertifyCodeTF;
}
//密码输入框
- (UITextField *)pwdTF{
if (!_pwdTF){
_pwdTF = [self createTFWithFrame:CGRectMake(FIT_X(20), self.vertifyCodeTF.frame.origin.y+self.vertifyCodeTF.frame.size.height+FIT_Y(10), FIT_X(200), FIT_Y(60)) placeholder:@"输入密码" tag:203];
}
return _pwdTF;
}
//密码验证
- (UITextField *)vertifyPwdTF{
if (!_vertifyPwdTF){
_vertifyPwdTF = [self createTFWithFrame:CGRectMake(FIT_X(20), self.pwdTF.frame.origin.y+self.pwdTF.frame.size.height+FIT_Y(10), FIT_X(200), FIT_Y(60)) placeholder:@"再次输入密码" tag:204];
}
return _vertifyPwdTF;
}
//注册按钮
- (UIButton *)registerBtn{
if (!_registerBtn) {
_registerBtn = [UIButton buttonWithType:UIButtonTypeCustom];
_registerBtn.frame = CGRectMake(FIT_X(20), self.vertifyPwdTF.frame.origin.y + self.vertifyPwdTF.frame.size.height+FIT_Y(15), SCR_W-FIT_X(40),FIT_Y(60));
_registerBtn.backgroundColor = [UIColor orangeColor];
[_registerBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
_registerBtn.titleLabel.font = [UIFont systemFontOfSize:24.];
[_registerBtn setTitle:@"注册" forState:UIControlStateNormal];
[_registerBtn addTarget:self action:@selector(registerBtnHandle:) forControlEvents:UIControlEventTouchUpInside];
}
return _registerBtn;
}
#pragma mark - initWithFrame
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor grayColor];
[self addSubview:self.shutBtn];
[self addSubview:self.phoneTF];
[self addSubview:self.getVertifyCodeBtn];
[self addSubview:self.vertifyCodeTF];
[self addSubview:self.pwdTF];
[self addSubview:self.vertifyPwdTF];
[self addSubview:self.registerBtn];
}
return self;
}
#pragma mark - UITextFieldDelegate
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
//获取当前文本
NSString *content = [textField.text stringByReplacingCharactersInRange:range withString:string];
if (textField.tag == 201) {
return content.length <= 11;//手机号
}
else if (textField.tag == 202){
return content.length <= 4;//验证码
}
else{
return YES;
}
}
#pragma mark - Touches
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
@end