LoginSignup
1
1

More than 5 years have passed since last update.

テーブルビューでMVCモデル分けをしてみた

Last updated at Posted at 2017-10-11

前回の記事に引き続き、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の更新を行う際は、以下のような流れで考えています。

  1. contorollerクラスが、Viewクラスからデータを受け取る。
  2. modelクラスが、controllerクラスからデータを受け取り、DBに保存する。
  3. modelクラスが、controllerクラスにデリゲート通知を送る。
  4. controllerクラス、上記通知を受け取り、デリゲートメソッドを実行する。
  5. controllerクラスのデリゲートメソッドで、modelクラスにデータソース作成を依頼する
  6. modelクラスがデータソースの作成をし、controllerクラスに返す。
  7. controllerクラスは、modelクラスからデータソースを受け取り、(そのまま)viewクラスにデータを渡す。
  8. controllerクラスのリロードメソッドを呼び、viewクラスを更新する。
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1