博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS实例浅谈MVC (附登陆注册demo)
阅读量:4143 次
发布时间:2019-05-25

本文共 9368 字,大约阅读时间需要 31 分钟。

文章目录

MVC简介

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写。

MVC开始是存在于桌面程序中的,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。比如一批统计数据可以分别用柱状图、饼图来表示。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。

MVC编程模式

MVC模式虽然是iOS编程中使用最广泛的模式,但论起复杂程度,MVC模式可以算是众多设计模式之首。通常情况下,MVC模式需要综合使用target-action模式、delegate模式、Notification或KVO模式等。

  • Model(模型)表示应用程序核心(比如数据库记录列表),通常模型对象负责在数据库中存取数据。
  • View(视图)显示数据(数据库记录),通常视图是依据模型数据创建的。
  • Controller(控制器)处理输入(写入数据库记录),通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。

MVC原理可简化为下图:

在这里插入图片描述

  • Controller和View之间可以通信,Controllor通过outlet(输出口)控制View,View可以通过target-action、delegate或者data source(想想UITableVeiwDatasource)来和Controller通信;
  • Controller在接收到View传过来的交互事件(View就是完成让人和程序的交互的呀,比如按B1按钮)之后,经过一些判断和处理,把需要Model处理的事件递交给Model处理(比如刚才的例子中的保存到数据库),Controller对Model使用的是API;
  • Model在处理完数据之后,如果有需要,会通过Notification或者KVO的方式告知Controller,事件已经处理完,Controller再经过判断和处理之后,考虑下一步要怎么办(是默默无闻的在后台操作,还是需要更新View,这得看Controller的“脸色”行事)。这里的无线天线很有意思,Model只负责发送通知,具体谁接收这个通知并处理它,Model并不关心,这一点非常重要,是理解Notification模式的关键。
  • Model和View之间不直接通信!
    以上摘自

注册登陆实例

  • 新建M V C三个文件夹(需要几个View建几套文件夹)
  • 新建一个名为VView的类,继承自UIView(以登陆界面为例)
  • 新建一个名为MModel的类,继承自NSObject
  • 拖到相应的文件夹下,注册界面同上
  • 新建一个跳转的界面,用于登陆后跳转

完成以后应该是这样:

在这里插入图片描述
按照MVC的思想,VView中应该写两个textField和两个button(以登陆界面为例),写好后的代码如下:

#import 
NS_ASSUME_NONNULL_BEGIN@interface VView : UIView@property (nonatomic, strong) UIButton *loadBtn;@property (nonatomic, strong) UIButton *registerBtn;@property (nonatomic, strong) UITextField *nameTextField;@property (nonatomic, strong) UITextField *passTextField;- (void)InitView; //view初始化@end
#import "VView.h"@implementation VView- (void)InitView {        _loadBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];    [_loadBtn setFrame:CGRectMake(80, 400, 100, 50)];    [_loadBtn setTitle:@"load" forState:UIControlStateNormal];    [_loadBtn setTitleColor:[UIColor blackColor] forState: UIControlStateNormal];    [self addSubview:_loadBtn];        _registerBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];    [_registerBtn setFrame:CGRectMake(230, 400, 100, 50)];    [_registerBtn setTitle:@"register" forState:UIControlStateNormal];    [_registerBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];    [self addSubview:_registerBtn];        _nameTextField = [[UITextField alloc] initWithFrame:CGRectMake(50, 200, 300, 50)];    _nameTextField.layer.masksToBounds = YES;    _nameTextField.layer.cornerRadius = 5;    _nameTextField.layer.borderWidth = 2;    _nameTextField.layer.borderColor = [UIColor blackColor].CGColor;    _nameTextField.placeholder = @"nameWord";    [self addSubview:_nameTextField];        _passTextField = [[UITextField alloc] initWithFrame:CGRectMake(50, 280, 300, 50)];    _passTextField.layer.masksToBounds = YES;    _passTextField.layer.cornerRadius = 5;    _passTextField.layer.borderWidth = 2;    _passTextField.layer.borderColor = [UIColor blackColor].CGColor;    _passTextField.secureTextEntry = YES;    _passTextField.placeholder = @"passWord";    [self addSubview:_passTextField];    }

会发现button里没有添加target-action方法,这是因为target-action方法需要设置一个target对象,在这个对象里调用action方法。按照MVC的思想,V里面不进行数据处理,而是要在C里面统一调控由C还是M来处理数据。本例中,我们是在C里面处理,所以我把targe-action方法写到C里面。

按照MVC的思想,M主要用于数据的处理,所以在这个案例中我将存放账号和密码的数组放入M中。

#import 
NS_ASSUME_NONNULL_BEGIN@interface MModel : NSObject@property (nonatomic, strong) NSMutableArray *nameArr;@property (nonatomic, strong) NSMutableArray *passArr;- (void)modelInit;//- (void)addName:(NSString *)name Pass:(NSString *)pass;@end
#import "MModel.h"@implementation MModel- (void)modelInit {        _nameArr = [[NSMutableArray alloc] init];    _passArr = [[NSMutableArray alloc] init];    [_nameArr addObject:@"123"];    [_passArr addObject:@"456"];    }

接下来就是C了,登陆注册需要使用协议来传值,传值的操作我在这里就不解释了,不懂的朋友可以看看博客,由于我在VView和MModel中定义的方法为实例方法,所以我需要实例化VView和MModel来调用这些方法:

#import 
#import "RViewController.h"#import "VView.h"#import "MModel.h"NS_ASSUME_NONNULL_BEGIN@interface ViewController : UIViewController
@property (nonatomic, strong) VView *myView;@property (nonatomic, strong) MModel *myModel;@end
#import "ViewController.h"#import "newViewController.h"#import "RViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view.        _myView = [[VView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];    [_myView InitView];    [_myView.loadBtn addTarget:self action:@selector(pressLoad) forControlEvents:UIControlEventTouchUpInside];    [_myView.registerBtn addTarget:self action:@selector(pressRegister) forControlEvents:UIControlEventTouchUpInside];    [self.view addSubview:_myView];        _myModel = [[MModel alloc] init];    [_myModel modelInit];    }- (void)pressLoad {        for (int i = 0; i < _myModel.nameArr.count; i++) {        if ([_myView.nameTextField.text isEqualToString: _myModel.nameArr[i]] && [_myView.passTextField.text isEqualToString:_myModel.passArr[i]]) {            newViewController *new = [[newViewController alloc] init];            [self presentViewController:new animated:NO completion:nil];        }    }}- (void)pressRegister {        RViewController *RegistViewController = [[RViewController alloc] init];    RegistViewController.registerDelegate = self;    [self presentViewController:RegistViewController animated:NO completion:nil];        }- (void)passName:(NSString *)name passPass:(NSString *)pass {        [_myModel.nameArr addObject:name];    [_myModel.passArr addObject:pass];    }

到这里登陆界面就写完了,注册界面原理和它一样,我就只放代码不进行过多的讲解了

因为没有数据的改变,所以RModel里没有任何东西

#import 
NS_ASSUME_NONNULL_BEGIN@interface RModel : NSObject@endNS_ASSUME_NONNULL_END
#import "RModel.h"@implementation RModel@end

RView:

#import 
NS_ASSUME_NONNULL_BEGIN@interface RView : UIView@property (nonatomic, strong) UIButton *loadBtn;@property (nonatomic, strong) UIButton *registerBtn;@property (nonatomic, strong) UITextField *nameTextField;@property (nonatomic, strong) UITextField *passTextField;- (void)InitView; //view初始化@end
#import "RView.h"@implementation RView- (void)InitView {        _loadBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];    [_loadBtn setFrame:CGRectMake(80, 400, 100, 50)];    [_loadBtn setTitle:@"back" forState:UIControlStateNormal];    [_loadBtn setTitleColor:[UIColor blackColor] forState: UIControlStateNormal];    [self addSubview:_loadBtn];        _registerBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];    [_registerBtn setFrame:CGRectMake(230, 400, 100, 50)];    [_registerBtn setTitle:@"Ok" forState:UIControlStateNormal];    [_registerBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];    [self addSubview:_registerBtn];        _nameTextField = [[UITextField alloc] initWithFrame:CGRectMake(50, 200, 300, 50)];    _nameTextField.layer.masksToBounds = YES;    _nameTextField.layer.cornerRadius = 5;    _nameTextField.layer.borderWidth = 2;    _nameTextField.layer.borderColor = [UIColor blackColor].CGColor;    _nameTextField.placeholder = @"nameWord";    [self addSubview:_nameTextField];        _passTextField = [[UITextField alloc] initWithFrame:CGRectMake(50, 280, 300, 50)];    _passTextField.layer.masksToBounds = YES;    _passTextField.layer.cornerRadius = 5;    _passTextField.layer.borderWidth = 2;    _passTextField.layer.borderColor = [UIColor blackColor].CGColor;    _passTextField.secureTextEntry = YES;    _passTextField.placeholder = @"passWord";    [self addSubview:_passTextField];    }

RViewController:

#import 
#import "RView.h"#import "RModel.h"NS_ASSUME_NONNULL_BEGIN@protocol RegisterDelegate
- (void)passName:(NSString *)name passPass:(NSString *)pass;@end@interface RViewController : UIViewController@property (nonatomic, strong) RView *myView;@property (nonatomic, strong) RModel *myModel;@property id
registerDelegate;@end
#import "RViewController.h"#import "ViewController.h"@interface RViewController ()@end@implementation RViewController- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view.        _myView = [[RView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];    [_myView InitView];    [_myView.loadBtn addTarget:self action:@selector(pressLoad) forControlEvents:UIControlEventTouchUpInside];    [_myView.registerBtn addTarget:self action:@selector(pressRegister) forControlEvents:UIControlEventTouchUpInside];    [self.view addSubview:_myView];        _myModel = [[RModel alloc] init];    }- (void)pressLoad {        [self dismissViewControllerAnimated:NO completion:nil];    }- (void)pressRegister{        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"你已成功注册!" preferredStyle:UIAlertControllerStyleAlert];    UIAlertAction *sure = [UIAlertAction actionWithTitle:@"sure" style:UIAlertActionStyleCancel handler:^(UIAlertAction *sure) {        if ([self->_registerDelegate respondsToSelector:@selector(passName:passPass:)]) {            [self->_registerDelegate passName:self->_myView.nameTextField.text passPass:self->_myView.passTextField.text];        }         [self dismissViewControllerAnimated:NO completion:nil];    }];    [alert addAction:sure];    [self presentViewController:alert animated:NO completion:nil];    }

转载地址:http://cwkti.baihongyu.com/

你可能感兴趣的文章
EasySwift/YXJPageControl 高扩展的PageController
查看>>
EasySwift/YXJCycleView 任意视图的无限循环轮播图,可以是本地图片,可以是任意的view,可以是远程图片,再加文字描述岂不更好,pageController也支持高度自定义。
查看>>
EasySwift/EasyCountDownButton 一个超级好用的倒计时Button
查看>>
EasySwift/YXJSlideBar 类似网页新闻的菜单
查看>>
EasySwift/YXJOnePixelLine 极其方便的画出真正的一个像素的线
查看>>
EasySwift/YXJSwipeTableViewCell UITableViewCell左右滑动出现更多按钮,按钮高度自定义
查看>>
EasySwift/YXJLinksButton 比如注册协议,往往下面有一条横线。也是HTML种a标签的默认效果
查看>>
EasySwift/YXJKxMenu 微信,qq首页右上角的菜单效果
查看>>
EasySwift/EasyDropDownMenu 类似美团,糯米,大众点评的筛选排序菜单
查看>>
Mac 查看 80 端口被占的pid
查看>>
libxml/tree.h file not found解决办法
查看>>
【tomcat】There are no resources that can be added or removed from the server. .
查看>>
JAVA事务的概念
查看>>
Windows平台下Git(gitblit)服务器搭建
查看>>
重置oracle 11G的system、sys密码
查看>>
ORA-28000: the account is locked-的解决办法
查看>>
[详解]为什么选择Spring Boot作为微服务的入门级微框架(PPT)
查看>>
CocoaPods解决Unable to add a source with url
查看>>
Swift3.0--GCD
查看>>
Carthage使用心得-让自己的项目支持Carthage
查看>>