iOS实例浅谈MVC (附登陆注册demo)

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 <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; //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 <Foundation/Foundation.h>

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 <UIKit/UIKit.h>
#import "RViewController.h"
#import "VView.h"
#import "MModel.h"

NS_ASSUME_NONNULL_BEGIN

@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];
    // 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 <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface RModel : NSObject

@end

NS_ASSUME_NONNULL_END
#import "RModel.h"

@implementation RModel


@end

RView:


#import <UIKit/UIKit.h>

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 <UIKit/UIKit.h>
#import "RView.h"
#import "RModel.h"

NS_ASSUME_NONNULL_BEGIN
@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];
    // 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];
    
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值