运用了一些第三方库
- 运用的代码是OC代码。
- 运用了Masonry布局,AFNetworking网络请求,MJExtension,SDWebImage,MJRefresh。
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的这个思路。