前回の記事に引き続き、MVCモデルにおけるデリゲートの使い方に関して備忘録を残します。
テーブルビューのクラス分けに挑戦してみました。
その際にデリゲートの使い方が見えてきたので、ここに残そうと思います。
今回は、DBの代わりにArrayを使っています。
View
※この他にラベルを3つ配置したカスタムセルクラスを用意しています。
TableViewProvider.h
@import UIKit;
#import <Foundation/Foundation.h>
#import "CellDataModel.h"
@interface TableViewProvider : NSObject <UITableViewDataSource>
@property (strong, nonatomic) NSArray<CellDataModel *> *dataList;
@end
TableViewProvider.m
@import UIKit;
#import "TableViewProvider.h"
#import "CustomCell.h"
@interface TableViewProvider ()
@end
@implementation TableViewProvider
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.dataList.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:[CustomCell identifier] forIndexPath:indexPath];
cell.numberLabel.text = self.dataList[indexPath.row].numdber;
cell.nameLabel.text = [NSString stringWithFormat:@"名前:%@", self.dataList[indexPath.row].name];
cell.adressLabel.text = [NSString stringWithFormat:@"住居:%@", self.dataList[indexPath.row].adress];
return cell;
}
@end
Controller
.hには設定なし
ListViewController.m
#import "ListViewController.h"
#import "CustomCell.h"
#import "TableViewProvider.h"
#import "DataModel.h"
@interface ListViewController () <UITableViewDelegate, DataModelDelegate>
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (nonatomic) TableViewProvider *provider;
@property (nonatomic) DataModel *dataModel;
@property (nonatomic) int counter;
@end
@implementation ListViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setupTableView];
self.dataModel = [[DataModel alloc] init];
self.dataModel.delegate = self;
[self.dataModel resetDatabase];
self.counter = 1;
}
- (void)setupTableView {
UINib *nib = [UINib nibWithNibName:[CustomCell nibName] bundle:nil];
[self.tableView registerNib:nib forCellReuseIdentifier:[CustomCell identifier]];
self.provider = [[TableViewProvider alloc] init];
self.tableView.delegate = self;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
CustomCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSLog(@"%@", cell.nameLabel.text);
}
- (IBAction)createTableViewCell:(id)sender {
NSString *number = [NSString stringWithFormat:@"%d", self.counter];
[self.dataModel allItems:number name:@"hogehoge" adress:@"tokyo"];
self.counter++;
self.provider.dataList = self.dataModel.items;
self.tableView.dataSource = self.provider;
[self.tableView reloadData];
}
// 今回のArrayを用いたコードでは必要ないが、モデルクラスからリロードをかける必要がある場合は、デリゲートメソッドとして使用する
- (void)reloadData {
[self.tableView reloadData];
}
@end
Model
DataModel.h
#import <Foundation/Foundation.h>
#import "CellDataModel.h"
@protocol DataModelDelegate <NSObject>
// デリゲートメソッドを使用する場合に記載
- (void)reloadData;
@end
@interface DataModel : NSObject
// デリゲートメソッドを使用する場合に記載
@property (weak, nonatomic) id<DataModelDelegate> delegate;
@property (strong, nonatomic) NSMutableArray *items;
- (void)resetDatabase;
- (void)allItems:(NSString *)number name:(NSString *)name adress:(NSString *)adress;
@end
DataModel.m
#import "DataModel.h"
#import "CellDataModel.h"
@interface DataModel ()
// DBのカラムの代わりのプロパティ
@property (strong, nonatomic) NSMutableArray *numberList;
@property (strong, nonatomic) NSMutableArray *nameList;
@property (strong, nonatomic) NSMutableArray *adressList;
@end
@implementation DataModel
- (void)allItems:(NSString *)number name:(NSString *)name adress:(NSString *)adress{
CellDataModel *item = [[CellDataModel alloc]initWithPropty:number name:name adress:adress];
[self.items addObject:item];
}
- (void)resetDatabase {
self.items = [@[] mutableCopy];
self.numberList = [@[] mutableCopy];
self.nameList = [@[] mutableCopy];
self.adressList = [@[] mutableCopy];
}
@end
データモデルとして、3つのプロパティを持ったCellDataModelクラスを別途用意してあります。
CellDataModel.h
#import <Foundation/Foundation.h>
@interface CellDataModel : NSObject
@property (strong, nonatomic)NSString *numdber;
@property (strong, nonatomic)NSString *name;
@property (strong, nonatomic)NSString *adress;
- (instancetype)initWithPropty:(NSString *)number name:(NSString *)name adress:(NSString *)adress;
@end
CellDataModel.h
#import "CellDataModel.h"
@implementation CellDataModel
- (instancetype)initWithPropty:(NSString *)number name:(NSString *)name adress:(NSString *)adress {
self = [super init];
if (self) {
self.numdber = number;
self.name = name;
self.adress = adress;
}
return self;
}
@end
まとめ
今回は、モデルはDBの代わりにArrayを使っていますが、適宜DBコードに置き換えて使っていこうと思います。
ちなみに、自作デリゲートを使ってModelクラスからViewの更新を行う際は、以下のような流れで考えています。
- contorollerクラスが、Viewクラスからデータを受け取る。
- modelクラスが、controllerクラスからデータを受け取り、DBに保存する。
- modelクラスが、controllerクラスにデリゲート通知を送る。
- controllerクラス、上記通知を受け取り、デリゲートメソッドを実行する。
- controllerクラスのデリゲートメソッドで、modelクラスにデータソース作成を依頼する
- modelクラスがデータソースの作成をし、controllerクラスに返す。
- controllerクラスは、modelクラスからデータソースを受け取り、(そのまま)viewクラスにデータを渡す。
- controllerクラスのリロードメソッドを呼び、viewクラスを更新する。