iOS使用VIPER与UITableView

我有一个视图控制器,它包含一个表视图,所以我想问我应该把表视图数据源和委托放在哪里,如果它是一个外部对象,或者我可以在我的视图控制器中写它,如果我们说关于VIPER模式.

通常使用模式我这样做:

在viewDidLoad我请求一些流程从演示者像self.presenter.showSongs()

演示者包含交互器和showSongs方法我请求一些来自交互器的数据,如:self.interactor.loadSongs()

当歌曲准备好返回到视图控制器时,我再次使用演示者来确定如何在视图控制器中显示该数据.但我的问题我应该怎么用表视图的数据源?

解决方法

首先,您的View不应该向Presenter询​​问数据 – 它违反了VIPER架构.

视图是被动的.它等待演示者给它内容显示;它从来没有要求Presenter的数据.

至于你的问题:
在Presenter中保持当前视图状态最好,包括所有数据.因为它是基于状态提供VIPER部件之间的通信.

但是以其他方式,Presenter不应该知道UIKit的任何内容,所以UITableViewDataSource和UITableViewDelegate应该是View层的一部分.

为了使您的ViewController保持良好状态并以“SOLID”的方式进行,最好将DataSource和Delegate保存在单独的文件中.但这些部分仍然应该知道演示者要求数据.所以我更喜欢在扩展ViewController中

所有模块应该是这样的:

视图

ViewController.h

extern Nsstring * const TableViewCellIdentifier;

@interface ViewController
@end

ViewController.m

Nsstring * const TableViewCellIdentifier = @"CellIdentifier";

@implemntation ViewController

- (void)viewDidLoad {
   [super viewDidLoad];
   [self.presenter setupView];
}

- (void)refreshSongs {
   [self.tableView reloadData];
}

@end

ViewController TableViewDataSource.h

@interface ViewController (TableViewDataSource) <UITableViewDataSource>
@end

ViewController TableViewDataSource.m

@implementation ItemsListViewController (TableViewDataSource)
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [self.presenter songsCount];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
   UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

   Song *song = [self.presenter songAtIndex:[indexPath.row]];
   // Configure cell

   return cell;
}
@end

ViewController TableViewDelegate.h

@interface ViewController (TableViewDelegate) <UITableViewDelegate>
@end

ViewController TableViewDelegate.m

@implementation ItemsListViewController (TableViewDelegate)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    Song *song = [self.presenter songAtIndex:[indexPath.row]];
    [self.presenter didSelectItemAtIndex:indexPath.row];
}
@end

主持人

Presenter.m

@interface Presenter()
@property(nonatomic,strong)NSArray *songs;
@end

@implementation Presenter
- (void)setupView {
  [self.interactor getSongs];
}

- (NSUInteger)songsCount {
   return [self.songs count];
}

- (Song *)songAtIndex:(NSInteger)index {
   return self.songs[index];
}

- (void)didLoadSongs:(NSArray *)songs {
   self.songs = songs;
   [self.userInterface refreshSongs];
}

@end

交互器

Interactor.m

@implementation Presenter
- (void)getSongs {
   [self.service getSongsWithCompletionHandler:^(NSArray *songs) {
      [self.presenter didLoadSongs:songs];
    }];
}
@end

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...