iOS开发自己尝试等装一下牛叉的demo

VTMagic 搭建一个iOS新闻类APP及使用心得

2018-06-15  本文已影响62人  _Andy_

对VTMagic 有一些 使用上的心得 写个新闻类demo 跟大家分享一下
点击 ZBNews 下载 查看代码
demo 所用接口是网络抓取 可能会在未来某个时候无法使用

  1. 因为作者九流书生 很长时间没有更新pods了,VTMagic 现在pods版本是1.2.4,并没有适配iOS11。 所以你如果使用pods 引用VTMagic 建议要用以下格式. 会多个属性displayCentered 和适配iOS11
pod 'VTMagic', :git => 'https://github.com/tianzhuo112/VTMagic.git'
  1. 上面提到displayCentered 属性 是被选中的menuItem是否居中显示 ,老版本VTMagic 被选中的menuItem 是不居中的。而是靠previewItems 属性控制的
/**
*  被选中的menuItem是否居中显示,默认NO
*/
@property (nonatomic, assign) BOOL displayCentered;

/**
*  导航菜单item的预览数,默认为1
*
*  @warning displayCentered为YES时,该属性无效
*/
@property (nonatomic, assign) NSUInteger previewItems;
  1. 如果 你的APP 要隐藏导航栏 ,并且还需要系统的返回滑动手势,不要使用
    [self.navigationController setNavigationBarHidden:YES animated:YES]; 此方法会屏蔽系统返回滑动手势。
    要使用 self.navigationController.navigationBar.hidden = YES;
    在要跳转的页面 有需要显示导航栏的页面
    在viewWillAppear 方法里self.navigationController.navigationBar.hidden = NO;即可
//MainViewController
- (void)viewWillAppear:(BOOL)animated {
   [super viewWillAppear:animated];
   //此方法会使 系统侧滑返回手势失效
   //[self.navigationController setNavigationBarHidden:YES animated:YES];
   self.navigationController.navigationBar.hidden = YES;
}
  1. 看各大新闻APP 如果把子视图比做ABC.. .都是在浏览A 界面自动加载数据后 在往右滑动到B界面 或是多个界面,在回到A界面时数据不会自动加载数据了,除非下拉刷新,或是过了一定时间在回到A界面才能在自动加载数据。 VTMagic是在在子视图控制器中加载数据的请求前 要加入此判断.
    另外建议在 viewWillDisappear 做取消网络请求和结束刷新的操作
- (void)viewDidAppear:(BOOL)animated {
   [super viewDidAppear:animated];
  NSTimeInterval currentStamp = [[NSDate date] timeIntervalSince1970];
   if (self.dataArray.count&& currentStamp - _mainModel.lastTime < timeOut) {
       return; //必须加此判断  否则会出现数据重复加载
   }
   _mainModel.lastTime = currentStamp;
      //网络请求方法 或是 进入刷新状态
}

- (void)viewWillDisappear:(BOOL)animated {
   [super viewWillDisappear:animated];
   [self.viewModel cancelRequestWithMenuInfo:_menuInfo]; // 取消不必要的网络请求
   [self endRefresh];
}
  1. 预加载 这是VTMagic 尤为突出的 功能,但是部分人并不会使用此功能 ,包括作者的VTMagic Demo 也没有完全发挥此功能。
    我说的前提是 needPreloading=YES;//预加载开关 为开的状态 ,如果不用预加载的 请忽略本条。
    如果对VTMagic有了解的同学都知道 VTMagic 的子视图 都是在 viewDidAppear 进行网络请求,
    可我们在进行页面左右滑动的时候并没有 视觉上并没有感受到预加载,感觉还是从A滑动到了B页面显示全部后B才去加载数据的,如果在加上自动触发下拉刷新的动画 B页面很长时间才显示UI。 这和理想状态不符。
- (void)viewDidAppear:(BOOL)animated {
   [super viewDidAppear:animated];
   self.collectionView.scrollsToTop = YES;
   NSInteger pageIndex = [self vtm_pageIndex];
   SLog(@"当前页面索引: %ld", (long)pageIndex);
   [self requestListData];//加载数据
}
loading111GIF.gif

健康栏目 滑动到 命理栏目 命理栏目已经全部出来 之后才去加载的。这是预加载吗? 你看到预加载了吗? 肯定不是。

.h
@class MenuInfo;
@interface RACChannelViewController : BaseViewController
/**
*  菜单信息
*/
@property (nonatomic, strong) MenuInfo *menuInfo;
@end

在.m 重写 大家在VTMagic Demo里看到 setMenuInfo 都是看里面写的 读缓存的逻辑
其实 这个方法才是预加载的入口 当我们加载A界面 时,B界面的这个方法也会触发 依次触发 。就可以实现预加载了。我们可以先看下log

.m
#pragma mark - accessor methods
- (void)setMenuInfo:(MenuInfo *)menuInfo {
   _menuInfo = menuInfo;
    NSLog(@"预加载: %@",_menuInfo.title);
   //VTMagic官方Dome 加载列表缓存的方法  [self loadLocalData];
}
loading222Gif.gif

log 显示 当我们在移动到一个栏目时 会预加载当前栏目的下一个栏目

下面我们就 - (void)setMenuInfo:(MenuInfo *)menuInfo 中加入网络请求并在请求成功后刷新列表

#pragma mark - accessor methods
- (void)setMenuInfo:(MenuInfo *)menuInfo {
   _menuInfo = menuInfo;
   _page=1;
   [self.viewModel requestListDataWithPage:_page menuInfo:_menuInfo requestType:ZBRequestTypeRefresh];
   SLog(@"预加载: %@",_menuInfo.title);

   //VTMagic官方Dome  加载列表缓存的方法  [self loadLocalData]; 
}
loading333GIF.gif

可以看到在setMenuInfo 因为会预加载下一个栏目,我们在当前栏目时,下一个栏目进行了网络请求 并在请求成功后刷新列表 滑动可看到已经提前加载好下一个栏目的页面了

  1. 页面重用 缓存
    这个重用机制 作者已经说的很清楚了 看下图


    1F74CB23-2A2A-44CF-A515-28D55A34CC5C.png

但是因为重用机制 使得页面在左右滑动俩个子视图页面后,会出现页面数据混乱的问题,这个作者也给出了解决方案

- (void)viewDidDisappear:(BOOL)animated {
   [super viewDidDisappear:animated];
    [self savePageInfo];  // //保存页面数据 VTMagic官方Dome 的方法
}

#pragma mark - accessor methods
- (void)setMenuInfo:(MenuInfo *)menuInfo {
   _menuInfo = menuInfo;
   _page=1;
   SLog(@"预加载: %@",_menuInfo.title);
   [self loadLocalData];// VTMagic官方Dome 加载列表缓存的方法
}

//VTMagic官方Dome 的方法
- (void)savePageInfo {
    [[DataManager sharedInstance] savePageInfo:self.dataArray menuId:_menuInfo.menu_id];
}
- (void)loadLocalData {
    NSArray *cacheList = [[DataManager sharedInstance] pageInfoWithMenuId:_menuInfo.menu_id];
    [self.dataArray addObjectsFromArray:cacheList];
    [self.tableView reloadData];
}

就是在A页面 消失时 触发viewDidDisappear 保存当前页面的列表数组,在用户滑动回 A 页面时 提前触发setMenuInfo 取出列表数组 重新刷新列表
虽然这个方法运行没有问题,但是并不是最优的解决方案

下面放出我的解决方案,也许作者本人没有这么 做

- (void)viewDidAppear:(BOOL)animated {
   [super viewDidAppear:animated];
   self.tableView.scrollsToTop = YES;
    _page=1;
   [self request:_page requestType:ZBRequestTypeRefresh];//重新数据
}

#pragma mark - accessor methods
- (void)setMenuInfo:(MenuInfo *)menuInfo {
   _menuInfo = menuInfo;
/*
   //伪代码
     if(有缓存){
     //读取缓存 刷新列表  
     }else{
      //重新请求 刷新列表 存储缓存
     }
*/
   SLog(@"预加载: %@",_menuInfo.title);
   _page=1;
    [self request:_page requestType:ZBRequestTypeCache];     //如有缓存使用缓存,无缓存重新加载
}

在viewDidAppear 重新请求或者调用下拉刷新
在setMenuInfo 方法里 进行(如果有缓存使用缓存,无缓存重新加载)策略的请求 这样既满足的预加载, 有兼顾了缓存。

进一步解释步骤:当栏目在A时 , 栏目B已经执行setMenuInfo ,假如B没有缓存 进行了重新请求并存储缓存,栏目A浏览一会 滑动到栏目B, 栏目B执行viewDidAppear 进行刷新请求 并更新了缓存, 同时栏目C执行setMenuInfo ,依次滑动并都请求成功A->B->C->D->E->F,都是同样的步骤.
当用户网往回滑动A<-B<-C<-D<-E<-F 也是先执行 setMenuInfo 方法,因为都浏览过都请求成功了 都有了缓存,setMenuInfo 里面会执行读取缓存 的步骤。

另外在设置 页面可以清除缓存 ,之后在回到主页进行反复调试

request: requestType: 方法 最终调到是我封装的网络请求 ZBNetworking 里面就有这个策略 //如有缓存使用缓存,无缓存重新加载,简直是完美搭配 看最终效果

loading444GIF.gif
  1. 对于现在比较流行嵌套滚动 VTMagic 框架不支持 它的headerView 和底部容器是加载在一个UIView上面没法进行嵌套滚动 只有一个隐藏headerView的方法
    在子视图 调用一下
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
   CGFloat yOffset = scrollView.contentOffset.y;
   if (yOffset>0) {
       self.magicController.magicView.againstStatusBar = YES;
       [self.magicController.magicView setHeaderHidden:YES duration:0.35];
   }else{
       self.magicController.magicView.againstStatusBar = NO;
       [self.magicController.magicView setHeaderHidden:NO duration:0.35];
   }
}
loading555GIF.gif

先介绍这么多,以后再有领悟会补充。另外ZBNews中还实现了阅读日历 ,收藏,离线下载 功能 当然没有细致的制作UI 只是功能的展示 最后点击 ZBNews 下载

一直在努力学习中,大家多多包涵。

上一篇下一篇

猜你喜欢

热点阅读