本文共 9368 字,大约阅读时间需要 31 分钟。
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写。
MVC开始是存在于桌面程序中的,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。比如一批统计数据可以分别用柱状图、饼图来表示。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。MVC模式虽然是iOS编程中使用最广泛的模式,但论起复杂程度,MVC模式可以算是众多设计模式之首。通常情况下,MVC模式需要综合使用target-action模式、delegate模式、Notification或KVO模式等。
MVC原理可简化为下图:
完成以后应该是这样:
按照MVC的思想,VView中应该写两个textField和两个button(以登陆界面为例),写好后的代码如下:#importNS_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中。
#importNS_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里没有任何东西
#importNS_ASSUME_NONNULL_BEGIN@interface RModel : NSObject@endNS_ASSUME_NONNULL_END
#import "RModel.h"@implementation RModel@end
RView:
#importNS_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/