iOS使用VIPER和UITableView [英] iOS using VIPER with UITableView

查看:163
本文介绍了iOS使用VIPER和UITableView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a view controller which contains a table view, so I want to ask where should I put table view data source and delegate, should it be an external object or I can write it in my view controller if we say about VIPER pattern.

通常使用模式我这样做:

Normally using pattern I do this:

在viewDidLoad中我从presenter请求一些流,如 self.presenter.showSongs()

In viewDidLoad I request some flow from presenter like self.presenter.showSongs()

Presenter包含交互器,在showSongs方法中,我从交互器请求一些数据,如:self。 interactor.loadSongs()

Presenter contains interactor and in showSongs method I request some data from interactor like: self.interactor.loadSongs()

当歌曲准备好传回视图控制器时,我再次使用演示者来确定如何在视图控制器中显示这些数据。但我的问题是如何处理表视图的数据源?

When songs are ready to passing back to view controller I use presenter one more time to determine how this data should be display in view controller. But my question what should I do with datasource of table view?

推荐答案

首先,您的视图不应该询问来自Presenter的数据 - 这违反了VIPER架构。

First of all your View shouldn't ask data from Presenter - it's violation of VIPER architecture.

视图是被动的。它等待Presenter给它显示内容;它永远不会要求Presenter提供数据。

The View is passive. It waits for the Presenter to give it content to display; it never asks the Presenter for data.

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

As for you question: It's better to keep current view state in Presenter, including all data. Because it's providing communications between VIPER parts based on state.

但是以其他方式,Presenter不应该知道关于UIKit的任何信息,因此UITableViewDataSource和UITableViewDelegate应该是View层的一部分。

But in other way Presenter shouldn't know anything about UIKit, so UITableViewDataSource and UITableViewDelegate should be part of View layer.

为了使ViewController保持良好状态并以SOLID方式执行,最好将DataSource和Delegate保存在单独的文件中。但这些部分仍然应该知道主持人询问数据。所以我更喜欢在ViewController的扩展中做到这一点

To keep you ViewController in good shape and do it in 'SOLID' way, it's better to keep DataSource and Delegate in separate files. But these parts still should know about presenter to ask data. So I prefer to do it in Extension of ViewController

所有模块都应该是这样的:

All module should look something like that:

查看

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

Interactor.m

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

这篇关于iOS使用VIPER和UITableView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆