我看過很多代碼,其中將ViewModel設置爲表視圖數據源,許多代碼沒有。將viewModel設置爲表視圖數據源是錯誤的嗎?
1.在一段時間內將數據源設置到ViewModel是有意義的,因爲數據源方法主要處理表示邏輯。
2.另一方面,將ViewModel設置爲數據源意味着您正在實施cellForRowAtIndexPath
等,這使得它不獨立於UIKit
。
什麼是建築你的應用程序的最佳方式,請澄清一下?
我看過很多代碼,其中將ViewModel設置爲表視圖數據源,許多代碼沒有。將viewModel設置爲表視圖數據源是錯誤的嗎?
1.在一段時間內將數據源設置到ViewModel是有意義的,因爲數據源方法主要處理表示邏輯。
2.另一方面,將ViewModel設置爲數據源意味着您正在實施cellForRowAtIndexPath
等,這使得它不獨立於UIKit
。
什麼是建築你的應用程序的最佳方式,請澄清一下?
答案是,沒有最好的方式來構建應用程序。根據您的需求組織您的課程有很多好方法。 下面是我如何安排我的視圖模型,以顯示在表格視圖中的數據爲例:
PaymentSectionItem是我的ViewModel
PaymentSectionItem.h
@interface PaymentSectionItem : NSObject
@property (assign, nonatomic) NSUInteger itemID;
@property (strong, nonatomic) NSString *name;
@property (strong, nonatomic) NSArray *elements;
@property (assign, nonatomic) kTransactionType transactionType;
+ (NSArray<PaymentSectionItem *> *)allSectionItemsWithData;
@end
PaymentSectionItem.m
@implementation PaymentSectionItem
#pragma mark - Custom Accessors
- (NSString *)localizedTitle {
NSString *title = [NSString stringWithFormat:@"%@_section_title", self.name];
return NSLocalizedString(title, @"Section title");
}
- (NSString *)localizedDescription {
NSString *title = [NSString stringWithFormat:@"%@_section_description", self.name];
return NSLocalizedString(title, @"Section description");
}
#pragma mark - Constructor
- (instancetype)initWithSectionItem:(kSectionItem)sectionItem {
self = [super init];
if (self) {
[self setupFromHomeSectionItem:sectionItem];
}
return self;
}
#pragma mark - Private
- (void)setupFromHomeSectionItem:(kSectionItem)sectionItem {
self.itemID = sectionItem;
switch (sectionItem) {
case kSectionItem1: {
self.name = @"phones";
self.elements = [Payment findPaymentsType1];
break;
}
case kSectionItem2: {
self.name = @"autopay";
self.elements = [Payment findPaymentsType2];
break;
}
case kSectionItem3: {
self.name = @"trustfund";
self.elements = [Payment findPaymentsType3];
self.transactionType = kTransactionTypeTrustFund;
break;
}
case kSectionItem4: {
self.name = @"debitlink";
self.elements = [Payment findPaymentsType4];
self.transactionType = kTransactionTypeDebitLink;
break;
}
case kSectionItem5: {
self.name = @"pindebit";
self.elements = [Payment findPaymentsType5];
self.transactionType = kTransactionTypePINDebit;
break;
}
}
}
#pragma mark - Public
+ (NSArray<PaymentSectionItem *> *)allSectionItemsWithData {
NSMutableArray *items = [NSMutableArray new];
[items addObject:[[PaymentSectionItem alloc] initWithSectionItem:kSectionItem1]];
[items addObject:[[PaymentSectionItem alloc] initWithSectionItem:kSectionItem2]];
[items addObject:[[PaymentSectionItem alloc] initWithSectionItem:kSectionItem3]];
[items addObject:[[PaymentSectionItem alloc] initWithSectionItem:kSectionItem4]];
[items addObject:[[PaymentSectionItem alloc] initWithSectionItem:kSectionItem5]];
return items;
}
ViewController.h
- (void)viewDidLoad {
[super viewDidLoad];
self.items = [PaymentSectionItem allSectionItemsWithData];
}
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.items.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.items[section].elements.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
GTLAutoPaySectionItem *sectionItem = self.items[indexPath.section];
NSString *identifier = [self identifierForSectionItem:sectionItem atIndex:indexPath];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
UITableViewCell<PaymentCellProtocol> *paymentCell = (UITableViewCell<PaymentCellProtocol> *)cell;
[paymentCell setupCellFromValue:sectionItem.elements[indexPath.row] withSectionItem:sectionItem];
return cell;
}
正如你看到的,在我的情況我有很多路段表格視圖,每個部分都有元素。這正是我在ViewModel中所做的。隨意問你是否有其他問題。
否,將視圖模型設置爲數據源,充當數據模型是沒有錯誤的。
那麼,這本書說,保持M,V & C單獨的可讀性和可維護性。但是現在我們有了多種設計模式來保持簡單。基本上,在模型中,我們只存儲數據,而且它的操作是在視圖級完成的,這是實現視圖的好方法。
你不能總是有一個緊密耦合或鬆散耦合五,它取決於這兩個的複雜性。
讓我等待其他有知識的人在接受任何答案之前回復。無論如何感謝您的回覆。 –
視圖模型
什麼你的建議是沒有錯的。在我看來,視圖模型只是簡單的邏輯,就像字體和顏色一樣。據我所知,沒有人宣佈這個規則,但我希望視圖模型很簡單。
在我看來,您的表格視圖所在的位置應與您的模型無關。假設你的tableView的superview是一個UITableViewCell。在那種情況下,我會通過回調來連接邏輯。
所以回調就是這樣。
protocol EventTableViewCellDatasource: class {
func showTimesTableViewDatasource() -> UITableViewDataSource
}
,其細胞會做到這一點
class EventTableViewCell: UITableViewCell {
weak var datasource: EventTableViewCellDatasource?
@IBOutlet weak private var tableView: ShowTimesTableView! {
didSet {
tableView.dataSource = datasource?.showTimesTableViewDatasource()
}
}
...
嗨,如果視圖模型只需要字體和顏色,我們不能實現使用Xcode運行時屬性?或像pixate的東西?爲什麼你需要MVVM?正如我在評論Luzo的回答時所說的那樣,這使得MVVM不適用於許多ios應用程序或與其相關。 –
我沒有說字體和顏色。如果您可以找到一種使用Xcode運行時屬性分配字體的方法,那麼請隨意。這樣做沒有錯。我不會認爲視圖模型只是一個子類。 Xcode運行時屬性對我來說似乎也是一個視圖模型。所以我不明白你關於MVVM的問題。 – 2017-10-09 07:03:26
「我不認爲視圖模型只是一個子類」。哦好的。感謝您的回答。 –
我知道這個解決方案中,我一直在尋找 - 1,迅速解決2.對兩難困境的回答「應該在哪裏的cellForRowAtIndexPath:去?在vc或vm中,爲什麼? –
我也知道解決方法,你在哪裏編寫獲取行數的方法,表視圖部分以及獲取View Model內部單元配置數據並在VC中調用它們的方法。很有道理,但這不是一點兒矯枉過正?你真的不會減少你VC中的行數,而且蘋果把「cellForRowAtIndexPath:」方法內部數據源中的od意味着它不完全屬於視圖層。希望你明白我的困境,我相信很多人也有這樣的困境。 –
@SuhasAithal:在輔助中減少行數,主要目標應該是使可讀性,可理解性,可維護性等等。行數並不是說代碼是錯誤的,它可以使其他人閱讀代碼。 –