MVC模式简介
MVC模式是iOS编程中使用最频繁和提到的最多次的设计模式之一
简介:
MVC模式–全称Model View Controller,模型(model)视图(view)控制器(controller) View–存放视图 Model–模型,模型一般都有很好的可复用性,统一管理一些数据。 Controller–控制器,充当一个CPU的功能,即该应用程序所有的工作都由Controller统一调控。负责处理View和Model的事件。
优点:
降低了各个环节耦合性,优化Controller的代码量。
原理:
MVC模式需要综合使用target-action,delegate,Notification,KVO模式等 Controller和View之间可以通信,Controller通过outlet(输出口)控制View,View可以通过target-action,delegate或者data source来和Controller通信 controller在接收到View传过来的交互时间后,经过一些判断和处理,把需要Model处理的事件递交给Model处理,Controller对Model使用的是API Model在处理完数据后,如果有需要,会通过Notification或者KVO的方式告知Controller事件处理完毕。Controller经过判断和处理,考虑下一步要怎么做。 Model和View之间不直接通信
图片来自斯坦福大学的iOS一堂公开课上使用的实例图
实例
我们使用一个登陆注册案例来看看M、V、C各个部分分别干了什么样的工作
- 新建一个项目,在新建名为VView,RView的类,继承UIView
- 新建MModel,RModel的类继承NSObject
- 新建RViewControll的类继承UIViewController
- 在登陆注册的View里有两个UITextField和UIButton按钮
- 将存放账号和密码的数组放入MModel中
- 在ViewController中使用传值方法将登陆注册的账号密码传入相应界面。
- 在相应的界面接收传递的值
登陆页面 注册页面
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface RModel : NSObject
@end
NS_ASSUME_NONNULL_END
#import "RModel.h"
@implementation RModel
@end
#import <UIKit/UIKit.h>
@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;
@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 grayColor].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 grayColor].CGColor;
_passTextField.secureTextEntry = YES;
_passTextField.placeholder = @" passWord";
[self addSubview:_passTextField];
}
@end
#import <UIKit/UIKit.h>
#import "RView.h"
#import "RModel.h"
@protocol RegisterDelegate <NSObject>
- (void)passName:(NSString *)name passPass:(NSString *)pass;
@end
@interface RViewController : UIViewController
@property (nonatomic, strong) RView *myView;
@property (nonatomic, strong) RModel *myModel;
@property id <RegisterDelegate> registerDelegate;
@end
#import "RViewController.h"
#import "ViewController.h"
@interface RViewController ()
@end
@implementation RViewController
- (void)viewDidLoad {
[super viewDidLoad];
_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];
self.view.backgroundColor = [UIColor whiteColor];
}
- (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];
}
@end
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface MModel : NSObject
@property (nonatomic, strong) NSMutableArray *nameArr;
@property (nonatomic, strong) NSMutableArray *passArr;
- (void)modelInit;
@end
NS_ASSUME_NONNULL_END
#import "MModel.h"
@implementation MModel
- (void)modelInit {
_nameArr = [[NSMutableArray alloc] init];
_passArr = [[NSMutableArray alloc] init];
[_nameArr addObject:@"123"];
[_passArr addObject:@"456"];
}
@end
#import <UIKit/UIKit.h>
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;
@end
NS_ASSUME_NONNULL_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 grayColor].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 grayColor].CGColor;
_passTextField.placeholder = @" passWord";
[self addSubview:_passTextField];
}
@end
#import <UIKit/UIKit.h>
#import "RViewController.h"
#import "VView.h"
#import "MModel.h"
@interface ViewController : UIViewController
<RegisterDelegate>
@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];
_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];
}
@end
总结
我们在“M”中进行了数据的存储,在“V”中进行了UITextFielde和UIButton的创建添加,在“C”中实现了账号密码输入的正确与否的判断和登陆注册界面间的传值操作还有相应账号密码的保存。
|