Oc 登录注册布局

添加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

你可能感兴趣的:(Oc 登录注册布局)