Commit d31a8675 authored by 汪洋's avatar 汪洋

save progress

parent 8d4e5642
...@@ -27,7 +27,8 @@ ...@@ -27,7 +27,8 @@
D32ECC451D33943500AEF0D0 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D32ECC441D33943500AEF0D0 /* Launch Screen.storyboard */; }; D32ECC451D33943500AEF0D0 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D32ECC441D33943500AEF0D0 /* Launch Screen.storyboard */; };
D32ECC481D33946600AEF0D0 /* GMListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D32ECC471D33946600AEF0D0 /* GMListViewController.m */; }; D32ECC481D33946600AEF0D0 /* GMListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D32ECC471D33946600AEF0D0 /* GMListViewController.m */; };
D3AC686421075A290083DAAF /* GMSwiftTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3AC686321075A290083DAAF /* GMSwiftTest.swift */; }; D3AC686421075A290083DAAF /* GMSwiftTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3AC686321075A290083DAAF /* GMSwiftTest.swift */; };
D3EB0CC41D33968300EEDD8B /* GMListViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = D3EB0CC31D33968300EEDD8B /* GMListViewModel.m */; }; D3AC6866210813930083DAAF /* GMSwiftListController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3AC6865210813930083DAAF /* GMSwiftListController.swift */; };
D3AC68682108A0970083DAAF /* GMSwiftListVIewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3AC68672108A0970083DAAF /* GMSwiftListVIewModel.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
...@@ -75,8 +76,8 @@ ...@@ -75,8 +76,8 @@
D32ECC461D33946600AEF0D0 /* GMListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GMListViewController.h; sourceTree = "<group>"; }; D32ECC461D33946600AEF0D0 /* GMListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GMListViewController.h; sourceTree = "<group>"; };
D32ECC471D33946600AEF0D0 /* GMListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GMListViewController.m; sourceTree = "<group>"; }; D32ECC471D33946600AEF0D0 /* GMListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GMListViewController.m; sourceTree = "<group>"; };
D3AC686321075A290083DAAF /* GMSwiftTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GMSwiftTest.swift; sourceTree = "<group>"; }; D3AC686321075A290083DAAF /* GMSwiftTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GMSwiftTest.swift; sourceTree = "<group>"; };
D3EB0CC21D33968300EEDD8B /* GMListViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GMListViewModel.h; sourceTree = "<group>"; }; D3AC6865210813930083DAAF /* GMSwiftListController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GMSwiftListController.swift; sourceTree = "<group>"; };
D3EB0CC31D33968300EEDD8B /* GMListViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GMListViewModel.m; sourceTree = "<group>"; }; D3AC68672108A0970083DAAF /* GMSwiftListVIewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GMSwiftListVIewModel.swift; sourceTree = "<group>"; };
E10ABE29C983D16788B32755 /* Pods-GMBase_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GMBase_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-GMBase_Tests/Pods-GMBase_Tests.debug.xcconfig"; sourceTree = "<group>"; }; E10ABE29C983D16788B32755 /* Pods-GMBase_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GMBase_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-GMBase_Tests/Pods-GMBase_Tests.debug.xcconfig"; sourceTree = "<group>"; };
FC7ED23958C6EFD0277A557F /* GMBase.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = GMBase.podspec; path = ../GMBase.podspec; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; FC7ED23958C6EFD0277A557F /* GMBase.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = GMBase.podspec; path = ../GMBase.podspec; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
/* End PBXFileReference section */ /* End PBXFileReference section */
...@@ -151,10 +152,10 @@ ...@@ -151,10 +152,10 @@
6003F5A6195388D20070C39A /* GMViewController.m */, 6003F5A6195388D20070C39A /* GMViewController.m */,
D32ECC461D33946600AEF0D0 /* GMListViewController.h */, D32ECC461D33946600AEF0D0 /* GMListViewController.h */,
D32ECC471D33946600AEF0D0 /* GMListViewController.m */, D32ECC471D33946600AEF0D0 /* GMListViewController.m */,
D3EB0CC21D33968300EEDD8B /* GMListViewModel.h */,
D3EB0CC31D33968300EEDD8B /* GMListViewModel.m */,
D32ECC411D33840600AEF0D0 /* GMDetailController.h */, D32ECC411D33840600AEF0D0 /* GMDetailController.h */,
D32ECC421D33840600AEF0D0 /* GMDetailController.m */, D32ECC421D33840600AEF0D0 /* GMDetailController.m */,
D3AC6865210813930083DAAF /* GMSwiftListController.swift */,
D3AC68672108A0970083DAAF /* GMSwiftListVIewModel.swift */,
D3AC686321075A290083DAAF /* GMSwiftTest.swift */, D3AC686321075A290083DAAF /* GMSwiftTest.swift */,
6003F5A8195388D20070C39A /* Images.xcassets */, 6003F5A8195388D20070C39A /* Images.xcassets */,
6003F594195388D20070C39A /* Supporting Files */, 6003F594195388D20070C39A /* Supporting Files */,
...@@ -406,9 +407,10 @@ ...@@ -406,9 +407,10 @@
6003F59E195388D20070C39A /* GMAppDelegate.m in Sources */, 6003F59E195388D20070C39A /* GMAppDelegate.m in Sources */,
6003F5A7195388D20070C39A /* GMViewController.m in Sources */, 6003F5A7195388D20070C39A /* GMViewController.m in Sources */,
D32ECC431D33840600AEF0D0 /* GMDetailController.m in Sources */, D32ECC431D33840600AEF0D0 /* GMDetailController.m in Sources */,
D3EB0CC41D33968300EEDD8B /* GMListViewModel.m in Sources */,
D3AC686421075A290083DAAF /* GMSwiftTest.swift in Sources */, D3AC686421075A290083DAAF /* GMSwiftTest.swift in Sources */,
6003F59A195388D20070C39A /* main.m in Sources */, 6003F59A195388D20070C39A /* main.m in Sources */,
D3AC68682108A0970083DAAF /* GMSwiftListVIewModel.swift in Sources */,
D3AC6866210813930083DAAF /* GMSwiftListController.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
......
...@@ -2,3 +2,4 @@ ...@@ -2,3 +2,4 @@
// Use this file to import your target's public headers that you would like to expose to Swift. // Use this file to import your target's public headers that you would like to expose to Swift.
// //
@import GMBase;
...@@ -7,8 +7,6 @@ ...@@ -7,8 +7,6 @@
// //
@import GMBase; @import GMBase;
#import "GMListViewModel.h"
@interface GMListViewController : WMBaseListViewController @interface GMListViewController : WMBaseListViewController
@property (nonatomic, strong) GMListViewModel *viewModel;
@end @end
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
// //
#import "GMListViewController.h" #import "GMListViewController.h"
#import "GMListViewModel.h"
@interface GMListViewController () @interface GMListViewController ()
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
- (void)initController { - (void)initController {
[super initController]; [super initController];
self.viewModel = [GMListViewModel new];
_cellHeight = 40; _cellHeight = 40;
_cellIdentifier = @"cell"; _cellIdentifier = @"cell";
} }
......
//
// GMListViewModel.h
// GMBase
//
// Created by wangyang on 16/7/11.
// Copyright © 2016年 wangyang. All rights reserved.
//
@import GMBase;
@interface GMListViewModel : GMListViewModel
@end
//
// GMListViewModel.m
// GMBase
//
// Created by wangyang on 16/7/11.
// Copyright © 2016年 wangyang. All rights reserved.
//
#import "GMListViewModel.h"
@implementation GMListViewModel
- (instancetype)init
{
self = [super init];
if (self) {
_remoteUrl = @"/api/index/v3?version=5.9.5";
}
return self;
}
- (void)buildModelWithRemoteDic:(NSDictionary *)dic {
[self.dataArray addObjectsFromArray:dic[@"data"][@"diaries"]];
}
@end
//
// GMSwiftListController.swift
// GMBase_Example
//
// Created by wangyang on 2018/7/25.
// Copyright © 2018年 wangyang. All rights reserved.
//
import UIKit
class GMSwiftListController: WMBaseListViewController {
var viewModel: GMSwiftListVIewModel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
//
// GMSwiftListVIewModel.swift
// GMBase_Example
//
// Created by wangyang on 2018/7/25.
// Copyright © 2018年 wangyang. All rights reserved.
//
import UIKit
class GMSwiftListVIewModel: GMListViewModel {
}
...@@ -20,6 +20,10 @@ typedef NS_ENUM(NSUInteger, GMListViewPageType) { ...@@ -20,6 +20,10 @@ typedef NS_ENUM(NSUInteger, GMListViewPageType) {
GMListViewPageTypeOffset, GMListViewPageTypeOffset,
}; };
@protocol GMListViewModel <NSObject>
@property (nonatomic, strong) id<GMListViewModel> viewModel;
@end
@interface GMListViewModel : WMViewModel { @interface GMListViewModel : WMViewModel {
/** @brief 列表数据远程请求Url地址 */ /** @brief 列表数据远程请求Url地址 */
NSString *_remoteUrl; NSString *_remoteUrl;
......
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
1. 使用fetchRemoteDataComplete,在ListController中删除KVO 1. 使用fetchRemoteDataComplete,在ListController中删除KVO
2. 在complete最后改变isRefreshing等标记位 2. 在complete最后改变isRefreshing等标记位
3. 让刷新与加载更多不能同时进行 3. 让刷新与加载更多不能同时进行
4. 。。。 4. 尝试协议:GMListViewModel
*/ */
- (void)fetchRemoteData { - (void)fetchRemoteData {
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
@synthesize collectionViewLayout = _collectionViewLayout; @synthesize collectionViewLayout = _collectionViewLayout;
- (void)initController{ - (void)initController{
[super initController]; [super initController];
self.viewModel = [[GMListViewModel alloc] init]; self.viewModel = [[GMListViewModel alloc] init];
_needHeaderRefresh = YES; _needHeaderRefresh = YES;
...@@ -30,11 +29,8 @@ ...@@ -30,11 +29,8 @@
_immediateLoad = YES; _immediateLoad = YES;
} }
- (void)viewDidLoad{ - (void)viewDidLoad{
[super viewDidLoad]; [super viewDidLoad];
[self addKVO];
[self.view addSubview:self.collectionView]; [self.view addSubview:self.collectionView];
[_collectionView mas_makeConstraints:^(MASConstraintMaker *make) { [_collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
...@@ -66,48 +62,31 @@ ...@@ -66,48 +62,31 @@
}]; }];
} }
- (void)fetchDataSuccess {
[self hideLoading];
_collectionView.hidden = NO;
- (void)addKVO // if ([[_viewModel fetchDataSuccess] boolValue]) {
{ if (YES) {
[self.viewModel addObserver:self forKeyPath:@"fetchDataSuccess" options:NSKeyValueObservingOptionNew context:NULL]; if ([[self.viewModel dataArray] count] == 0 && [self.viewModel fetchDataNilMsg]) {
} [self showEmptyView:GMEmptyViewTypeEmpty];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ } else {
if ([keyPath isEqualToString:@"fetchDataSuccess"] && object == self.viewModel) { [self hideEmptyView];
[self hideLoading];
_collectionView.hidden = NO;
if ([[_viewModel fetchDataSuccess] boolValue]) {
if ([[self.viewModel dataArray] count] == 0 && [self.viewModel fetchDataNilMsg]) {
[self showEmptyView:GMEmptyViewTypeEmpty];
} else {
[self hideEmptyView];
}
}else{
[self showEmptyView:GMEmptyViewTypeException];
}
// 调用reloadData,并不会立即执行,而是下更新周期来了之后才可以。
// 将 endRefreshing 与 endRefreshing 放到后面的好处就是此时可以利用 updateOtherUIData 做点额外的事。比如判断mj_header.isRefreshing
[self updateOtherUIData];
if (_collectionView) {
[_collectionView reloadData];
[_collectionView.mj_header endRefreshing];
[_collectionView.mj_footer endRefreshing];
} }
}else{
[self showEmptyView:GMEmptyViewTypeException];
} }
}
- (void)dealloc{
[self removeKVO];
if (self.isViewLoaded) { // 调用reloadData,并不会立即执行,而是下更新周期来了之后才可以。
[self.viewModel removeObserver:self forKeyPath:@"fetchDataSuccess"]; // 将 endRefreshing 与 endRefreshing 放到后面的好处就是此时可以利用 updateOtherUIData 做点额外的事。比如判断mj_header.isRefreshing
[self updateOtherUIData];
if (_collectionView) {
[_collectionView reloadData];
[_collectionView.mj_header endRefreshing];
[_collectionView.mj_footer endRefreshing];
} }
} }
- (void)removeKVO{
}
/** /**
* @brief 下拉刷新 * @brief 下拉刷新
*/ */
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#import <UITableView_FDTemplateLayoutCell/UITableView+FDTemplateLayoutCell.h> #import <UITableView_FDTemplateLayoutCell/UITableView+FDTemplateLayoutCell.h>
#import "GMListViewModel.h" #import "GMListViewModel.h"
@interface WMBaseListViewController : WMBaseViewController<UITableViewDelegate,UITableViewDataSource> @interface WMBaseListViewController : WMBaseViewController <UITableViewDelegate, UITableViewDataSource, GMListViewModel, UIScrollViewDelegate>
{ {
UITableView *_table; UITableView *_table;
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
} }
/** @brief viewModel*/ /** @brief viewModel*/
@property (nonatomic,strong) GMListViewModel *viewModel; @property (nonatomic, strong) id<GMListViewModel> viewModel;
@property (nonatomic, strong) UITableView *table; @property (nonatomic, strong) UITableView *table;
......
...@@ -35,8 +35,6 @@ ...@@ -35,8 +35,6 @@
- (void)viewDidLoad { - (void)viewDidLoad {
[super viewDidLoad]; [super viewDidLoad];
[self addKVO];
_table = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 0) style:_tableStyle]; _table = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 0) style:_tableStyle];
_table.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag; _table.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
_table.separatorStyle = UITableViewCellSeparatorStyleNone; _table.separatorStyle = UITableViewCellSeparatorStyleNone;
...@@ -153,46 +151,29 @@ ...@@ -153,46 +151,29 @@
[self.viewModel handleFooterRereshing]; [self.viewModel handleFooterRereshing];
} }
#pragma - mark View Model Handle - (void)fetchDataSuccess {
- (void)addKVO [self hideLoading];
{ self.table.hidden = NO;
[self.viewModel addObserver:self forKeyPath:@"fetchDataSuccess" options:NSKeyValueObservingOptionNew context:NULL];
}
- (void)removeKVO{
// 因为fetchDataSuccess是在viewDidLoad中监听的,所以需要一个判断
if ([self isViewLoaded]) {
[self.viewModel removeObserver:self forKeyPath:@"fetchDataSuccess"];
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ // if ([[_viewModel fetchDataSuccess] boolValue]) {
if ([keyPath isEqualToString:@"fetchDataSuccess"] && object == self.viewModel) { if (YES) {
[self hideLoading]; if ([[self.viewModel dataArray] count] == 0 && [self.viewModel fetchDataNilMsg]) {
if ([[self.viewModel fetchDataSuccess] boolValue]) { [self showEmptyView:GMEmptyViewTypeEmpty];
if ([[self.viewModel dataArray] count] == 0) { } else {
[self showEmptyView:GMEmptyViewTypeEmpty]; [self hideEmptyView];
}else {
[self hideEmptyView];
}
}else{
[self showEmptyView:GMEmptyViewTypeException];
}
if (_table!=nil) {
[_table reloadData];
[_table.mj_header endRefreshing];
[_table.mj_footer endRefreshing];
} }
}else{
[self updateOtherUIData]; [self showEmptyView:GMEmptyViewTypeException];
} }
}
- (void)dealloc{ // 调用reloadData,并不会立即执行,而是下更新周期来了之后才可以。
[self removeKVO]; // 将 endRefreshing 与 endRefreshing 放到后面的好处就是此时可以利用 updateOtherUIData 做点额外的事。比如判断mj_header.isRefreshing
[self updateOtherUIData];
if (self.table) {
[self.table reloadData];
[self.table.mj_header endRefreshing];
[self.table.mj_footer endRefreshing];
}
} }
- (void)showEmptyView:(GMEmptyViewType)type { - (void)showEmptyView:(GMEmptyViewType)type {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment