Commit d31a8675 authored by 汪洋's avatar 汪洋

save progress

parent 8d4e5642
......@@ -27,7 +27,8 @@
D32ECC451D33943500AEF0D0 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D32ECC441D33943500AEF0D0 /* Launch Screen.storyboard */; };
D32ECC481D33946600AEF0D0 /* GMListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D32ECC471D33946600AEF0D0 /* GMListViewController.m */; };
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 */
/* Begin PBXContainerItemProxy section */
......@@ -75,8 +76,8 @@
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>"; };
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>"; };
D3EB0CC31D33968300EEDD8B /* GMListViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GMListViewModel.m; sourceTree = "<group>"; };
D3AC6865210813930083DAAF /* GMSwiftListController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GMSwiftListController.swift; 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>"; };
FC7ED23958C6EFD0277A557F /* GMBase.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = GMBase.podspec; path = ../GMBase.podspec; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
/* End PBXFileReference section */
......@@ -151,10 +152,10 @@
6003F5A6195388D20070C39A /* GMViewController.m */,
D32ECC461D33946600AEF0D0 /* GMListViewController.h */,
D32ECC471D33946600AEF0D0 /* GMListViewController.m */,
D3EB0CC21D33968300EEDD8B /* GMListViewModel.h */,
D3EB0CC31D33968300EEDD8B /* GMListViewModel.m */,
D32ECC411D33840600AEF0D0 /* GMDetailController.h */,
D32ECC421D33840600AEF0D0 /* GMDetailController.m */,
D3AC6865210813930083DAAF /* GMSwiftListController.swift */,
D3AC68672108A0970083DAAF /* GMSwiftListVIewModel.swift */,
D3AC686321075A290083DAAF /* GMSwiftTest.swift */,
6003F5A8195388D20070C39A /* Images.xcassets */,
6003F594195388D20070C39A /* Supporting Files */,
......@@ -406,9 +407,10 @@
6003F59E195388D20070C39A /* GMAppDelegate.m in Sources */,
6003F5A7195388D20070C39A /* GMViewController.m in Sources */,
D32ECC431D33840600AEF0D0 /* GMDetailController.m in Sources */,
D3EB0CC41D33968300EEDD8B /* GMListViewModel.m in Sources */,
D3AC686421075A290083DAAF /* GMSwiftTest.swift in Sources */,
6003F59A195388D20070C39A /* main.m in Sources */,
D3AC68682108A0970083DAAF /* GMSwiftListVIewModel.swift in Sources */,
D3AC6866210813930083DAAF /* GMSwiftListController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
......@@ -2,3 +2,4 @@
// Use this file to import your target's public headers that you would like to expose to Swift.
//
@import GMBase;
......@@ -7,8 +7,6 @@
//
@import GMBase;
#import "GMListViewModel.h"
@interface GMListViewController : WMBaseListViewController
@property (nonatomic, strong) GMListViewModel *viewModel;
@end
......@@ -7,7 +7,7 @@
//
#import "GMListViewController.h"
#import "GMListViewModel.h"
@interface GMListViewController ()
......@@ -18,7 +18,6 @@
- (void)initController {
[super initController];
self.viewModel = [GMListViewModel new];
_cellHeight = 40;
_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) {
GMListViewPageTypeOffset,
};
@protocol GMListViewModel <NSObject>
@property (nonatomic, strong) id<GMListViewModel> viewModel;
@end
@interface GMListViewModel : WMViewModel {
/** @brief 列表数据远程请求Url地址 */
NSString *_remoteUrl;
......
......@@ -49,7 +49,7 @@
1. 使用fetchRemoteDataComplete,在ListController中删除KVO
2. 在complete最后改变isRefreshing等标记位
3. 让刷新与加载更多不能同时进行
4. 。。。
4. 尝试协议:GMListViewModel
*/
- (void)fetchRemoteData {
......
......@@ -22,7 +22,6 @@
@synthesize collectionViewLayout = _collectionViewLayout;
- (void)initController{
[super initController];
self.viewModel = [[GMListViewModel alloc] init];
_needHeaderRefresh = YES;
......@@ -30,11 +29,8 @@
_immediateLoad = YES;
}
- (void)viewDidLoad{
[super viewDidLoad];
[self addKVO];
[self.view addSubview:self.collectionView];
[_collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
......@@ -66,48 +62,31 @@
}];
}
- (void)fetchDataSuccess {
[self hideLoading];
_collectionView.hidden = NO;
- (void)addKVO
{
[self.viewModel addObserver:self forKeyPath:@"fetchDataSuccess" options:NSKeyValueObservingOptionNew context:NULL];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if ([keyPath isEqualToString:@"fetchDataSuccess"] && object == self.viewModel) {
[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];
// if ([[_viewModel fetchDataSuccess] boolValue]) {
if (YES) {
if ([[self.viewModel dataArray] count] == 0 && [self.viewModel fetchDataNilMsg]) {
[self showEmptyView:GMEmptyViewTypeEmpty];
} else {
[self hideEmptyView];
}
}else{
[self showEmptyView:GMEmptyViewTypeException];
}
}
- (void)dealloc{
[self removeKVO];
if (self.isViewLoaded) {
[self.viewModel removeObserver:self forKeyPath:@"fetchDataSuccess"];
// 调用reloadData,并不会立即执行,而是下更新周期来了之后才可以。
// 将 endRefreshing 与 endRefreshing 放到后面的好处就是此时可以利用 updateOtherUIData 做点额外的事。比如判断mj_header.isRefreshing
[self updateOtherUIData];
if (_collectionView) {
[_collectionView reloadData];
[_collectionView.mj_header endRefreshing];
[_collectionView.mj_footer endRefreshing];
}
}
- (void)removeKVO{
}
/**
* @brief 下拉刷新
*/
......
......@@ -10,7 +10,7 @@
#import <UITableView_FDTemplateLayoutCell/UITableView+FDTemplateLayoutCell.h>
#import "GMListViewModel.h"
@interface WMBaseListViewController : WMBaseViewController<UITableViewDelegate,UITableViewDataSource>
@interface WMBaseListViewController : WMBaseViewController <UITableViewDelegate, UITableViewDataSource, GMListViewModel, UIScrollViewDelegate>
{
UITableView *_table;
......@@ -32,7 +32,7 @@
}
/** @brief viewModel*/
@property (nonatomic,strong) GMListViewModel *viewModel;
@property (nonatomic, strong) id<GMListViewModel> viewModel;
@property (nonatomic, strong) UITableView *table;
......
......@@ -35,8 +35,6 @@
- (void)viewDidLoad {
[super viewDidLoad];
[self addKVO];
_table = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 0) style:_tableStyle];
_table.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
_table.separatorStyle = UITableViewCellSeparatorStyleNone;
......@@ -153,46 +151,29 @@
[self.viewModel handleFooterRereshing];
}
#pragma - mark View Model Handle
- (void)addKVO
{
[self.viewModel addObserver:self forKeyPath:@"fetchDataSuccess" options:NSKeyValueObservingOptionNew context:NULL];
}
- (void)removeKVO{
// 因为fetchDataSuccess是在viewDidLoad中监听的,所以需要一个判断
if ([self isViewLoaded]) {
[self.viewModel removeObserver:self forKeyPath:@"fetchDataSuccess"];
}
}
- (void)fetchDataSuccess {
[self hideLoading];
self.table.hidden = NO;
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if ([keyPath isEqualToString:@"fetchDataSuccess"] && object == self.viewModel) {
[self hideLoading];
if ([[self.viewModel fetchDataSuccess] boolValue]) {
if ([[self.viewModel dataArray] count] == 0) {
[self showEmptyView:GMEmptyViewTypeEmpty];
}else {
[self hideEmptyView];
}
}else{
[self showEmptyView:GMEmptyViewTypeException];
}
if (_table!=nil) {
[_table reloadData];
[_table.mj_header endRefreshing];
[_table.mj_footer endRefreshing];
// if ([[_viewModel fetchDataSuccess] boolValue]) {
if (YES) {
if ([[self.viewModel dataArray] count] == 0 && [self.viewModel fetchDataNilMsg]) {
[self showEmptyView:GMEmptyViewTypeEmpty];
} else {
[self hideEmptyView];
}
[self updateOtherUIData];
}else{
[self showEmptyView:GMEmptyViewTypeException];
}
}
- (void)dealloc{
[self removeKVO];
// 调用reloadData,并不会立即执行,而是下更新周期来了之后才可以。
// 将 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 {
......
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