iOS - MVC架构
程序员文章站
2022-03-24 15:06:10
文章目录MVC简介MVC模式Control->Model/ViewModel->ControlView->Controller简单登陆的demoModel:ViewControlMVC简介MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写。MVC旨在让Model和View不直接通信,而是通过Controller通信,从而达到解耦的目的。简单来说MVC模式能够完成各司其职的任务模式,由于降低了各个环节的...
MVC简介
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写。
- MVC旨在让Model和View不直接通信,而是通过Controller通信,从而达到解耦的目的。简单来说MVC模式能够完成各司其职的任务模式,由于降低了各个环节的耦合性,大大优化Controller的代码量,当程序调试时,如果某一个功能没有按照既定的模式工作,可以很方便的定位到到底是Controller还是View还是Model出了问题,而且还利于程序的可复用性。、
- 但是由于它系统结构和实现的复杂性,可能会降低运行效率,不适合小型中等规模的应用程序。
MVC模式
- Model和View之间不直接通信!
Control->Model/View
直接在Controller中引入并实例化Model和View(按我的理解就是直接调用)
Model.m中
#import "MModel.h"
@implementation MModel
- (void)modelInit {
_nameArr = [[NSMutableArray alloc] init];
_passArr = [[NSMutableArray alloc] init];
[_nameArr addObject:@"123"];
[_passArr addObject:@"456"];
}
control.m中
_myModel = [[MModel alloc] init];
[_myModel modelInit];
Model->Control
-
KVO(监听)
Controller通过监听,监听Model的每个属性的变化来做出响应事件 -
Notification(通知)
Model中创建一个NSNotificationCenter,在Controller中,创建一个方法来接收通知。当Model发生变化时, 他会发送一个通知,而Controller会接收通知
View->Controller
-
target-Action
Controller给View添加一个target,当用户的触摸事件发生时,view产生action,Controller接收到之后做出相应的响应。(常规理解就是写个按钮,触摸按钮触发事件) -
delegate 或 datasource
Controller可以作为view的代理,当View中检测到被触摸,他会通知Controller做出响应(这个界面间传值时也用到)
简单登陆的demo
- 简单的功能:默认的账号123密码789,输入账号密码后,并且是默认的,点击登陆,进入另一个空白视图,若账号密码错误,则弹出一个提示框。
- 概述:control中,通过代理回调,将密码和帐号数据传到model中,与model的帐号和密码进行比对,将比对的结果通过Notification通知给Controller,触发按钮事件。
- 创建三个文件夹,分别命名为M V C
- 新建LoginModel类,继承于NSObject,这里面主要存放数据,比如我的原始密码。
- 新建LoginView,继承于UIView,在View中,放相关的控件,比如输入框,按钮等
- 新建LoginViewController,继承于UIViewController,Control是主体。
Model:
通过Notification通知给Controller
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface LandModel : NSObject
- (void)checkNames:(NSString *)username withPassword:(NSString *)password;
@end
NS_ASSUME_NONNULL_END
#import "LandModel.h"
@implementation LandModel
- (void)checkNames: (NSString *)username withPassword:(NSString *)password {
if([username isEqualToString:@"123"] && [password isEqualToString:@"789"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"landSuccessful" object:self];
}else {
[[NSNotificationCenter defaultCenter] postNotificationName:@"landFail" object:self];
}
}
@end
View
代理,在control中实现代理回调。
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@protocol PassButtonDelegate <NSObject>
- (void)clickButton: (UIButton *)sender;
@end
@interface LandView : UIView
@property (nonatomic, strong) UITextField *accountTextField;
@property (nonatomic, strong) UITextField *passwordTextField;
@property (nonatomic, strong) UIButton *landButton;
@property (nonatomic, weak) id <PassButtonDelegate> delegate;
- (void)viewInit;
@end
NS_ASSUME_NONNULL_END
#import "LandView.h"
@implementation LandView
- (void)viewInit {
_accountTextField = [[UITextField alloc] init];
[_accountTextField setFrame:CGRectMake(100, 100, 200, 40)];
_accountTextField.layer.borderColor = [UIColor blackColor].CGColor;
_accountTextField.placeholder = @"请输入帐号";
_accountTextField.layer.borderWidth = 1;
[self addSubview:_accountTextField];
_passwordTextField = [[UITextField alloc] init];
[_passwordTextField setFrame:CGRectMake(100, 160, 200, 40)];
_passwordTextField.layer.borderColor = [UIColor blackColor].CGColor;
_passwordTextField.placeholder = @"请输入密码";
_passwordTextField.secureTextEntry = YES;
_passwordTextField.layer.borderWidth = 1;
[self addSubview:_passwordTextField];
_landButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[_landButton setFrame:CGRectMake(140, 220, 80, 40)];
[_landButton setTitle:@"登陆" forState:UIControlStateNormal];
[_landButton setTintColor:[UIColor blackColor]];
[_landButton addTarget:self action:@selector(pressLand:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:_landButton];
}
- (void)pressLand:(UIButton *)sender {
if([_delegate respondsToSelector:@selector(clickButton:)]) {
[_delegate clickButton:sender];
}
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
@end
Control
在Controller中实例化Model和View对其中的方法进行调用
#import <UIKit/UIKit.h>
#import "LandView.h"
#import "LandModel.h"
@interface ViewController : UIViewController <PassButtonDelegate>
@property (nonatomic, strong) LandView *landView;
@property (nonatomic, strong) LandModel *mModel;
@end
#import "ViewController.h"
#import "SuccessfullViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
_landView = [[LandView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[_landView viewInit];
_landView.delegate = self;
[self.view addSubview:_landView];
_mModel = [[LandModel alloc] init];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(landSuccessful:) name:@"landSuccessful" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(landFail:) name:@"landFail" object:nil];
}
- (void)clickButton:(UIButton *)sender {
[_mModel checkNames:_landView.accountTextField.text withPassword:_landView.passwordTextField.text];
}
- (void)landSuccessful:(NSNotification *)notification {
SuccessfullViewController *sviewController = [[SuccessfullViewController alloc] init];
sviewController.view.backgroundColor = [UIColor yellowColor];
[self presentViewController:sviewController animated:NO completion:nil];
}
- (void)landFail:(NSNotification *)notification {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"错误" message:@"帐号或密码输入错误" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:sureAction];
[self presentViewController:alertController animated:YES completion:nil];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter]removeObserver:self];
}
//回收键盘
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
本文地址:https://blog.csdn.net/weixin_45841522/article/details/108697180