运用了一些第三方库

  1. 运用的代码是OC代码。
  2. 运用了Masonry布局,AFNetworking网络请求,MJExtension,SDWebImage,MJRefresh。

MVC

我的mvc可能和主流的不太一样,也许和我之前用安卓的有一定的影响,我看别人写的mvc M是模型 V层是view C层是控制层。这之间的关系是紧密联系的M层负责对象模型的创建 V层用来处理绘制各控件 C层是用来连接M与V层。

但是我并是这么认为 我也不知道 我这样理解是不是对的我理解的M层是业务逻辑和实体模型 ,M模型单独的抽出来作为Bean,这样就可以理解为 网络数据的获取处理我放在M层减少了C层的代码。

详细过程看代码和文字描述

所说的只是登录界面的一段代码

如下:

项目的分层

ios mvvm使用 ios mvc mvvm mvp_#import

当项目分层创建好有利于我们的辨认 依次如下

ios mvvm使用 ios mvc mvvm mvp_ios_02

创建好后需要从布局下手 首先制作view

代码如下
LoginView.h中代码:

在头部中需要创建一个向C层使用的按钮的代理 onBtnLoginClick

#import <UIKit/UIKit.h>

//设置代理方法
@protocol LoginViewDelegate <NSObject>
- (void)onBtnLoginClick;
@end

@interface LoginView : UIView
//设置代理
@property (nonatomic, weak) id<LoginViewDelegate> delegate;

//用户名
@property(strong,nonatomic) UILabel *usernameLabel;
@property(strong,nonatomic) UITextField *usernameText;
@property(strong,nonatomic) UIImageView *usernameImage;

//密码
@property(strong,nonatomic)UILabel *passwordLabel;
@property(strong,nonatomic)UITextField *passwordText;
@property(strong,nonatomic)UIImageView *passwordImage;

//按钮
@property(strong,nonatomic) UIButton *btnSure;

@property(strong,nonatomic) UIButton *btnFpassword;

@property(strong,nonatomic) UIButton *btnRegister;

@property(nonatomic)BOOL isselect;

@property(nonatomic) NSInteger selectedIndex;

@property(strong,nonatomic)NSUserDefaults *userDefaults;

@end

LoginView.m中代码:

引用了上面#ifdef…#endif 可以省略了Masonry布局中的mas_这段话

#import "LoginView.h"

#ifdef __OBJC__

//define this constant if you want to use Masonry without the 'mas_' prefix
#define MAS_SHORTHAND

//define this constant if you want to enable auto-boxing for default syntax
#define MAS_SHORTHAND_GLOBALS

#import "Masonry.h"

#endif


@implementation LoginView

//添加布局
-(instancetype) init{
    self = [super init];
    if(self){
        //添加布局
        [self initView];
        //添加按钮事件
        [self buttonOnclick];
    }

    return self;
}

//添加布局
-(void)initView{
    //添加主布局
    UIView *mainView = [[UIView alloc] init];
    mainView.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed:@"login_bg.png"]];

    mainView.alpha = 0.95;
    [self addSubview:mainView];

    //主view的约束
    [mainView makeConstraints:^(MASConstraintMaker *make){
        make.left.equalTo(self).offset(0);
        make.right.equalTo(self).offset(0);
        make.top.equalTo(self).offset(0);
        make.bottom.equalTo(self).offset(0);

    }];

    //中间显示的view
    UIView *middleView = [[UIView alloc] init];
    [mainView addSubview:middleView];

    //添加约束
    [middleView makeConstraints:^(MASConstraintMaker *make){
        make.left.equalTo(mainView).offset(20);
        make.right.equalTo(mainView).offset(-20);
        make.top.equalTo(mainView).offset(170);
        make.height.equalTo(@170);

    }];

    //添加用户边框
    UIView *usernameView = [[UIView alloc] init];
    usernameView.layer.cornerRadius = 8;
    usernameView.layer.borderColor = [[UIColor whiteColor] CGColor];
    usernameView.layer.borderWidth = 1;
    [middleView addSubview:usernameView];

    [usernameView makeConstraints:^(MASConstraintMaker *make){
        make.left.equalTo(middleView).offset(10);
        make.right.equalTo(middleView).offset(-10);
        make.top.equalTo(middleView).offset(10);
        make.height.equalTo(@50);
    }];


    //添加文字框
    _usernameImage = [[UIImageView alloc] init];
    //_usernameLabel.text = @"用户名:";
    [_usernameImage setImage:[UIImage imageNamed:@"usernamex.png"]];
    //一定这么写居中 不然会报警告的
    //_usernameLabel.textAlignment = NSTextAlignmentCenter;
    //_usernameLabel.textColor = [UIColor whiteColor];
    [usernameView addSubview:_usernameImage];

    //添加约束
    [_usernameImage makeConstraints:^(MASConstraintMaker *make){
        make.left.equalTo(usernameView).offset(10);
        make.width.equalTo(@25);
        make.top.equalTo(usernameView).offset(15);
        make.height.equalTo(@25);
    }];

    //添加输入框
    _usernameText = [[UITextField alloc] init];
    _usernameText.textColor = [UIColor whiteColor];
    [self addSubview:_usernameText];
    [_usernameText makeConstraints:^(MASConstraintMaker *make){
        make.left.equalTo(_usernameImage).offset(35);
        make.width.equalTo(@220);
        make.top.equalTo(usernameView).offset(0);
        make.height.equalTo(@50);
    }];

    //添加密码框view
    UIView *passwordView = [[UIView alloc] init];
    passwordView.layer.cornerRadius = 8;
    passwordView.layer.borderColor = [[UIColor whiteColor] CGColor];
    passwordView.layer.borderWidth = 1;
    [middleView addSubview:passwordView];

    [passwordView makeConstraints:^(MASConstraintMaker *make){
        make.left.equalTo(middleView).offset(10);
        make.right.equalTo(middleView).offset(-10);
        make.top.equalTo(usernameView).offset(85);
        make.height.equalTo(@50);
    }];

    //添加密码文字框
    _passwordImage = [[UIImageView alloc] init];
    //_passwordImage.textColor = [UIColor whiteColor];
    [_passwordImage setImage:[UIImage imageNamed:@"passwordx.png"]];
    //_passwordLabel.text = @"密码:";
    [passwordView addSubview:_passwordImage];
    [_passwordImage makeConstraints:^(MASConstraintMaker *make){
        make.left.equalTo(passwordView).offset(10);
        make.width.equalTo(@25);
        make.top.equalTo(passwordView).offset(15);
        make.height.equalTo(@25);
    }];

    //添加密码框
    _passwordText = [[UITextField alloc] init];
    _passwordText.textColor = [UIColor whiteColor];
    [passwordView addSubview:_passwordText];
    [_passwordText makeConstraints:^(MASConstraintMaker *make){
        make.left.equalTo(_passwordImage).offset(35);
        make.width.equalTo(@220);
        make.top.equalTo(passwordView).offset(0);
        make.height.equalTo(@50);
    }];


    //确定按钮
    _btnSure = [[UIButton alloc] init];
    [_btnSure setTitle:@"登录" forState:UIControlStateNormal];
    _isselect = TRUE;
    if(_isselect){
        _btnSure.backgroundColor = [UIColor redColor];
    }

    _btnSure.layer.cornerRadius = 15;
    [mainView addSubview:_btnSure];
    [_btnSure makeConstraints:^(MASConstraintMaker *make){
        make.top.equalTo(middleView).offset(180);
        make.left.equalTo(mainView).offset(30);
        make.right.equalTo(mainView).offset(-30);
        make.height.equalTo(@50);
    }];

    //忘记密码按钮
    _btnFpassword = [[UIButton alloc] init];
    [_btnFpassword setTitle:@"忘记密码?" forState:UIControlStateNormal];
    //_btnFpassword.textAlignment = NSTextAlignmentCenter;
    [mainView addSubview:_btnFpassword];

    [_btnFpassword makeConstraints:^(MASConstraintMaker *make){
        make.top.equalTo(_btnSure).offset(65);
        make.left.equalTo(mainView).offset(30);
        make.right.equalTo(mainView).offset(-30);
        make.height.equalTo(@55);
    }];

    //下面再增加一个主要的栏目
    UIView *bottomView = [[UIView alloc] init];
    [mainView addSubview:bottomView];
    [bottomView makeConstraints:^(MASConstraintMaker *make){
        make.bottom.equalTo(mainView.bottom).offset(0);
        make.left.equalTo(mainView).offset(20);
        make.right.equalTo(mainView).offset(-20);
        make.height.equalTo(@80);
    }];

    UIView *b_topView = [[UIView alloc] init];
    b_topView.backgroundColor = [UIColor whiteColor];
    [bottomView addSubview:b_topView];
    [b_topView makeConstraints:^(MASConstraintMaker *make){
        make.top.equalTo(bottomView).offset(5);
        make.left.equalTo(bottomView).offset(0);
        make.right.equalTo(bottomView).offset(0);
        make.height.equalTo(@1);
    }];

    //注册账号
    _btnRegister = [[UIButton alloc] init];
    [_btnRegister setTitle:@"加入我们!" forState:UIControlStateNormal];
    [bottomView addSubview:_btnRegister];
    [_btnRegister makeConstraints:^(MASConstraintMaker *make){
        make.top.equalTo(b_topView).offset(10);
        make.left.equalTo(bottomView).offset(5);
        make.right.equalTo(bottomView).offset(-5);
        make.height.equalTo(@55);
    }];
}

//按钮点击事件
-(void)buttonOnclick{
    [_btnSure addTarget:self action:@selector(btnOnClick) forControlEvents:UIControlEventTouchUpInside];
}

//登录按钮代理
-(void)btnOnClick{
    if(self.delegate){
        [self.delegate onBtnLoginClick];
    }
}

@end

当完成上述的操作后找到服务器登录数据返回回来的Json数据 然后着手写Bean层的数据

通过 AFNetworking解析出来的数据(实际是NSDictionary字典类型的)并不是我们可以使用的 Bean(Model)对象 需要经过处理后才能使用

创建 UserBean.h
UserBean.m里面是没有东西的就不写了

#import <Foundation/Foundation.h>
@interface UserBean : NSObject <NSCoding, NSCopying>

@property (nonatomic, strong) NSString *message;
@property (nonatomic, strong) NSArray *user;
@property (nonatomic, assign) double code;

@end

但是发现这个 user是一个NSArray类型的 至此还需要创建一个Bean(Model)

创建User.h

刚刚所说的 AFNetworking解析出来是一个字典的类型并不是我们需要的Model对象类型 所有还需要在User.m层里面做一次处理

#import <Foundation/Foundation.h>

@interface User : NSObject <NSCoding, NSCopying>

@property (nonatomic, strong) NSString *phone;
@property (nonatomic, strong) NSString *password;
@property (nonatomic, assign) double userIdentifier;
@property (nonatomic, assign) double age;
@property (nonatomic, strong) NSString *username;
@property (nonatomic, strong) NSString *email;
@property (nonatomic, strong) NSString *sex;
@property (nonatomic, strong) NSString *hoby;

-(id)initWithDict:(NSDictionary*)dict;

@end

User.m里面代码

#import "User.h"
@implementation User

-(id)initWithDict:(NSDictionary*)dict{
    if(self = [super init]){
        self.username = dict[@"usrname"];
        self.password = dict[@"password"];
        self.age = [dict[@"age"] doubleValue];
        self.sex = dict[@"sex"];
        self.userIdentifier = [dict[@"userIdentifier"] doubleValue];
        self.phone = dict[@"phone"];
        self.email = dict[@"email"];
        self.hoby = dict[@"hoby"];

    }
    return self;
}

@end

再次建立一个UserModel
UserModel.h

#import "User.h"
#import "UserBean.h"

Model(Bean)对象模型创建完毕 创建 数据处理层 Model(业务逻辑和实体模型)

LoginModel.h 这一层是业务逻辑层(网络数据获取放在这层里面)

同样这里有四个代理

第一个是成功的时候需要在C层展示的
第二个是在错误的时候需要在C层展示的
第三个是…
详细看代码的注释

#import <Foundation/Foundation.h>
#import "UserModel.h"
#import "AppConfig.h"
#import "AFNetworking.h"
#import "MJExtension.h"

// 新建一个协议,协议的名字一般是由“类名+Delegate”
@protocol LoginModelDelegate <NSObject>

//成功的时候
- (void)loginSuccess:(int) code listUser:(NSArray*) array;
//错误的时候
- (void)loginError:(int) code message:(NSString *)message;
//失败的时候
- (void)loginFail:(int) code message:(NSString *)message;
//输入为空的时候
- (void)inputnull:(int) code message:(NSString *)message;

@end

@interface LoginModel : NSObject

@property(weak,nonatomic) id<LoginModelDelegate> delegate;

@property(nonatomic,strong) NSArray *listUser;

@property(nonatomic,strong) UserBean *user;

//获取消息信息
@property(nonatomic,strong) NSString *message;

//获取登录的接口
-(void)Loginusername:(NSString *)username Loginpassword:(NSString *) password;

@end

LoginModel.m层

#import "LoginModel.h"

@implementation LoginModel

-(instancetype)init{
    self = [super init];
    if(self){
        _listUser = [[NSArray alloc] init];
    }
    return self;
}

/*
 *  登录的方法
 */
-(void)Loginusername:(NSString *)username Loginpassword:(NSString *) password{
    //首先判断不能为空
    if(![username isEqual:@""]&&username!=nil&&username!=NULL&&![password isEqual:@""]&&password!=nil&&password!=NULL){

        NSString *strURL = BASE_URL;

        NSDictionary *dict = @{
                               @"action":@"loginUser",
                               @"username":username,
                               @"password":password
                               };

        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        [manager POST:strURL parameters:dict progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            NSLog(@"success--%@--%@",[responseObject class],responseObject);

            _user = [UserBean mj_objectWithKeyValues:responseObject];
            //成功
            if(_user.code==200&&[_user.user count]>0){
                if([_delegate respondsToSelector:@selector(loginSuccess:listUser:)]){
                    [_delegate loginSuccess:SUCCESS listUser:_user.user];
                }
            }else{
                //失败
                if([_delegate respondsToSelector:@selector(loginFail:message:)]){
                    [_delegate loginFail:FAIL message:LOGINFAILMESSAGE];
                }
            }
        } failure:^(NSURLSessionDataTask * task, NSError * error) {
            //打印错误
            NSLog(@"failure--%@",error.localizedDescription);
            if([_delegate respondsToSelector:@selector(loginError:message:)]){
                [_delegate loginError:ERROR message:error.localizedDescription];
            }
        }];
    }else{
        if([_delegate respondsToSelector:@selector(inputnull:message:)]){
            [_delegate inputnull:INPUTNULL message:INPUTNULLMESSAGE];
        }
    }
}

@end

接下来就是关键了组合 MV的C层

LoginController.h层

#import <UIKit/UIKit.h>
#import "LoginModel.h"
#import "LoginView.h"
#import "MHProgress.h"
#import "HpBarController.h"

@interface LoginController : UIViewController

@property(nonatomic,strong) NSString *message;

@property(nonatomic,assign) int code;

//定时器
@property(strong,nonatomic) NSTimer *timer;

@property(nonatomic,strong) LoginView *loginView;

@property(nonatomic,strong) LoginModel *loginModel;

//获取user
@property(nonatomic,strong) NSArray *listUser;

@property(nonatomic,strong) MHProgress *progress;

//存储状态
@property(strong,nonatomic)NSUserDefaults *userDefaults;

@end

LoginController.m层

在C层中要实现M层的代码和V的代理

MHProgress.h 是运用了一个对话框自定义的控件

#import "LoginController.h"

@interface LoginController ()<LoginViewDelegate,LoginModelDelegate,UITextFieldDelegate>
@end

@implementation LoginController

- (void)viewDidLoad {
    [super viewDidLoad];
    //背景颜色为白色
    self.view.backgroundColor = [UIColor whiteColor];

    _userDefaults = [NSUserDefaults standardUserDefaults];

    _loginView = [LoginView new];
    _loginModel = [LoginModel new];

    _loginView.frame = self.view.bounds;
    //添加到Controller这里面去
    [self.view addSubview:_loginView];

    _loginView.delegate = self;
    _loginModel.delegate = self;
    _loginView.usernameText.delegate = self;
    _loginView.passwordText.delegate = self;
}

#pragma mark 所有的代理
- (void)onBtnLoginClick{
    _progress = [[MHProgress alloc]
                     initWithType:MHPopViewTypeWrapContentWithTips
                     failedBlock:^(){
                         //[self AlertTips:@"网络错误!"];
                         //存储状态为真
                         [_userDefaults setBool:TRUE forKey:@"ISLOGIN"];
                         //进入的关键代码
                         UIApplication.sharedApplication.delegate.window.rootViewController = HpBarController.new;
                     }];
    [_progress showLoadingView];

    [_loginModel Loginusername:_loginView.usernameText.text Loginpassword:_loginView.passwordText.text];
}

//成功的时候
- (void)loginSuccess:(int) code listUser:(NSArray*) array{
    _code = code;
    _listUser = [array mutableCopy];

    //存储状态为真
    [_userDefaults setBool:TRUE forKey:@"ISLOGIN"];
    //进入的关键代码
    UIApplication.sharedApplication.delegate.window.rootViewController = HpBarController.new;
}

//错误的时候
- (void)loginError:(int) code message:(NSString *)message{
    _code = code;
    _message = message;
    [self AlertTips:_message];
}

//失败的时候
- (void)loginFail:(int) code message:(NSString *)message{
    _code = code;
    _message = message;
    [self AlertTips:_message];
}

//输入为空的时候
- (void)inputnull:(int) code message:(NSString *)message{
    _code = code;
    _message = message;
    [self AlertTips:_message];
}

//弹出来一个对话框
-(void)AlertTips:(NSString *) message{
    [_progress closeLoadingView]; // 关闭
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *yesAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
        _message = @"";
        _code = 0;
    }];
    [alertController addAction:yesAction];
    [self presentViewController:alertController animated:true completion:nil];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [_loginView.usernameText resignFirstResponder];
    [_loginView.passwordText resignFirstResponder];

    return YES;
}

//点击空白处让键盘隐藏起来
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    [_loginView.usernameText resignFirstResponder];
    [_loginView.passwordText resignFirstResponder];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

@end

以上就是登录的MVC的详细过程。

总体来说代码相当于简单易懂,关键在于理解MVC的这个思路。