常见的架构有 MVC、MVP 和 MVVM。下面分别用代码做下演示。
MVC
#import "ViewController.h"
#pragma mark - Model
@interface MZPerson : NSObject
@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *image;
@end
@implementation MZPerson
@end
#pragma mark - View
@class MZView;
@protocol MZClickDelegate <NSObject>
@optional
- (void)viewDidClicked:(MZView *)view;
@end
@interface MZView : UIView
@property (nonatomic, strong) MZPerson *model;
@property (nonatomic, weak) id<MZClickDelegate> delegate;
@end
@interface MZView ()
//特点: 将View内部的细节封装起来了,外界不知道View内部的具体实现
@property (nonatomic, strong) UIImageView *iconView;
@property (nonatomic, strong) UILabel *nameLabel;
@end
@implementation MZView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
UIImageView *iconView = [[UIImageView alloc] init];
iconView.frame = CGRectMake(0, 0, 100, 100);
[self addSubview:iconView];
_iconView = iconView;
UILabel *nameLabel = [[UILabel alloc] init];
nameLabel.frame = CGRectMake(0, 100, 100, 30);
nameLabel.textAlignment = NSTextAlignmentCenter;
[self addSubview:nameLabel];
_nameLabel = nameLabel;
}
return self;
}
- (void)setModel:(MZPerson *)model {
_model = model;
self.iconView.image = [UIImage imageNamed:model.image];
self.nameLabel.text = model.name;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
if ([self.delegate respondsToSelector:@selector(viewDidClicked:)]) {
[self.delegate viewDidClicked:self];
}
}
@end
#pragma mark - Controller
@interface ViewController ()<MZClickDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//view
MZView *view = [[MZView alloc] initWithFrame:CGRectMake(100, 100, 100, 150)];
view.delegate = self;
[self.view addSubview:view];
//model
MZPerson *model = [[MZPerson alloc] init];
model.name = @"路飞";
model.image = @"lufei";
//设置数据到view上
view.model = model;
}
//代理方法
- (void)viewDidClicked:(MZView *)view {
NSLog(@"控制器接收到view的点击");
}
@end
MVP
MVP与MVC的区别在于:MVP将MVC中控制器的逻辑抽离出来放到presenter里(每一个大的逻辑都可以抽成一个presenter)。
#import "ViewController.h"
#pragma mark - Model
@interface MZPerson : NSObject
@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *image;
@end
@implementation MZPerson
@end
#pragma mark - View
@class MZView;
@protocol MZClickDelegate <NSObject>
@optional
- (void)viewDidClicked:(MZView *)view;
@end
@interface MZView : UIView
@property (nonatomic, strong) MZPerson *model;
@property (nonatomic, weak) id<MZClickDelegate> delegate;
@end
@interface MZView ()
//特点: 将View内部的细节封装起来了,外界不知道View内部的具体实现
@property (nonatomic, strong) UIImageView *iconView;
@property (nonatomic, strong) UILabel *nameLabel;
@end
@implementation MZView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
UIImageView *iconView = [[UIImageView alloc] init];
iconView.frame = CGRectMake(0, 0, 100, 100);
[self addSubview:iconView];
_iconView = iconView;
UILabel *nameLabel = [[UILabel alloc] init];
nameLabel.frame = CGRectMake(0, 100, 100, 30);
nameLabel.textAlignment = NSTextAlignmentCenter;
[self addSubview:nameLabel];
_nameLabel = nameLabel;
}
return self;
}
- (void)setModel:(MZPerson *)model {
_model = model;
self.iconView.image = [UIImage imageNamed:model.image];
self.nameLabel.text = model.name;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
if ([self.delegate respondsToSelector:@selector(viewDidClicked:)]) {
[self.delegate viewDidClicked:self];
}
}
@end
#pragma mark - Presenter
@interface MZPresenter : NSObject<MZClickDelegate>
- (instancetype)initWithController:(UIViewController *)viewController;
@end
@implementation MZPresenter
- (instancetype)initWithController:(UIViewController *)viewController {
if (self = [super init]) {
//view
MZView *view = [[MZView alloc] initWithFrame:CGRectMake(100, 100, 100, 150)];
view.delegate = self;
[viewController.view addSubview:view];
//model
MZPerson *model = [[MZPerson alloc] init];
model.name = @"路飞";
model.image = @"lufei";
//设置数据到view上
view.model = model;
}
return self;
}
//代理方法
- (void)viewDidClicked:(MZView *)view {
NSLog(@"控制器接收到view的点击");
}
@end
#pragma mark - Controller
@interface ViewController ()
@property (strong, nonatomic) MZPresenter *presenter;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.presenter = [[MZPresenter alloc] initWithController:self];
}
@end
MVVM
#import "ViewController.h"
#import "NSObject+FBKVOController.h"
#pragma mark - Model
@interface MZPerson : NSObject
@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *image;
@end
@implementation MZPerson
@end
#pragma mark - View
@class MZView, MZViewModel;
@protocol MZClickDelegate <NSObject>
@optional
- (void)viewDidClicked:(MZView *)view;
@end
@interface MZView : UIView
@property (nonatomic, strong) MZViewModel *viewModel;
@property (nonatomic, weak) id<MZClickDelegate> delegate;
@end
@interface MZView ()
//特点: 将View内部的细节封装起来了,外界不知道View内部的具体实现
@property (nonatomic, strong) UIImageView *iconView;
@property (nonatomic, strong) UILabel *nameLabel;
@end
@implementation MZView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
UIImageView *iconView = [[UIImageView alloc] init];
iconView.frame = CGRectMake(0, 0, 100, 100);
[self addSubview:iconView];
_iconView = iconView;
UILabel *nameLabel = [[UILabel alloc] init];
nameLabel.frame = CGRectMake(0, 100, 100, 30);
nameLabel.textAlignment = NSTextAlignmentCenter;
[self addSubview:nameLabel];
_nameLabel = nameLabel;
}
return self;
}
- (void)setViewModel:(MZViewModel *)viewModel {
_viewModel = viewModel;
__weak typeof(self) waekSelf = self;
[self.KVOController observe:viewModel keyPath:@"name" options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary<NSKeyValueChangeKey,id> * _Nonnull change) {
waekSelf.nameLabel.text = change[NSKeyValueChangeNewKey];
}];
[self.KVOController observe:viewModel keyPath:@"image" options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary<NSKeyValueChangeKey,id> * _Nonnull change) {
waekSelf.iconView.image = [UIImage imageNamed:change[NSKeyValueChangeNewKey]];
}];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
if ([self.delegate respondsToSelector:@selector(viewDidClicked:)]) {
[self.delegate viewDidClicked:self];
}
}
@end
#pragma mark - Presenter
@interface MZViewModel : NSObject
- (instancetype)initWithController:(UIViewController *)viewController;
@end
@interface MZViewModel ()<MZClickDelegate>
@property (weak, nonatomic) UIViewController *controller;
@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *image;
@end
@implementation MZViewModel
- (instancetype)initWithController:(UIViewController *)viewController {
if (self = [super init]) {
self.controller = viewController;
//view
MZView *view = [[MZView alloc] initWithFrame:CGRectMake(100, 100, 100, 150)];
view.delegate = self;
view.viewModel = self;
[viewController.view addSubview:view];
//model
MZPerson *model = [[MZPerson alloc] init];
model.name = @"路飞";
model.image = @"lufei";
// 设置数据
self.name = model.name;
self.image = model.image;
}
return self;
}
//代理方法
- (void)viewDidClicked:(MZView *)view {
NSLog(@"控制器接收到view的点击");
}
@end
#pragma mark - Controller
@interface ViewController ()
@property (strong, nonatomic) MZViewModel *viewModel;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.viewModel = [[MZViewModel alloc] initWithController:self];
}
@end
网友评论