iOS MVC简单的原理

来源:互联网 发布:淘宝主账号不收取信息 编辑:程序博客网 时间:2024/06/07 03:41

运用了一些第三方库

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

第三方库的链接

  1. Masonry https://github.com/SnapKit/Masonry
  2. AFNetworking https://github.com/AFNetworking/AFNetworking
  3. MJExtension https://github.com/CoderMJLee/MJExtension
  4. SDWebImage https://github.com/rs/SDWebImage

MVC

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

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

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

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

如下:

项目的分层

这里写图片描述

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

这里写图片描述

创建好后需要从布局下手 首先制作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的这个思路。

如果觉得对你有用的话记得点个赞。

还有奉献一个iOS代码库

https://github.com/Tim9Liu9/TimLiu-iOS

详细的代码如下:

http://download.csdn.net/download/a1989214/9964692

原创粉丝点击