知乎日报

  一直想写点什么,可又不知道从什么开始写。新的一年开始了,想想总要有个好得开头吧,折腾了俩天总算是把自己的博客弄了出来。前几天抽时间写了一下仿知乎日报,当中遇到到一些小问题给大家简单分享一下。
  

首页

TopScrollView

  首页的页面结构大致是这样的,先在首页添加一个tableView,originY从20开始,并且为tableView添加一个空白的hearderView,如下所示

    其次在view上添加一个scrollView,originY从-45开始,scrollView刚刚到tableView的顶端如下所示
   通过判断tableView的offSet来移动scrollView的位置
 

1
2
3
4
5
6
7
8
9
10
11
CGFloat offSetY = tableView.contentOffset.y;
if (offSetY<=0&&offSetY>=-90) {
//当下拉时候,scrollView往下移动一半,高度增加一半,图片会看起来上下都变长了
scrollView.frame = CGRectMake(0, -45 - 0.5 * offSetY, kScreenWidth, 265 - 0.5 * offSetY);
//偏移值大于90了禁止移动
}else if(offSetY<-90){
tableView.contentOffset = CGPointMake(0, -90);
}else if(offSetY <= 500) {
//上拉的时候,scrollView也随之上移,这样就能看见statusBar了
self.y = -45 - offSetY;
}

  当然,在移动的同时,也应该设置naviBar的alpha,其中naviBar是自己手动添加的一个View而已

1
2
3
  if (offSetY<=0&&offSetY>=-90)  _naviBar.alpha = 0;
//随着上拉,改变naviBar的alpha
else if(offSetY <= 500) _naviBar.alpha = offSetY/200;

  继续拉动的话会出现图中所视情况,当section刚刚移动到naviBar的位置的时候naviBar将会隐藏,这时候要用到tableView的代理方法。然后依据tableViewHearder的黏性,在继续拉动就顺理成章了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
// 写成0 display 不会在0的section 执行
return section?sectionHeight:CGFLOAT_MIN;
}
//当带有hearderView的section的在屏幕显示的时候执行的代理方法
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
if (section == 0) {
_naviBar.height = 55;
_titleLabel.alpha = 1;
}
}
//当hearderView的section在屏幕消失的时候执行的代理方法
- (void)tableView:(UITableView *)tableView didEndDisplayingHeaderView:(UIView *)view forSection:(NSInteger)section {
if (section == 0) {
_naviBar.height = 20;
_titleLabel.alpha = 0;
}
}

新闻详情页

  仔细的观看知乎日报上拉加载下一页的时候发现会产生有滚动的动画,而不是单纯的更换页面内容,此时就要用到scrollView了

1
2
3
4
5
_scrollView.pagingEnabled = YES;
_scrollView.bounces = NO;
scrollView.contentSize = CGSizeMake(kScreenWidth, 3 * kScreenHeight);
_scrollView.contentOffset = CGPointMake(0, kScreenHeight);
_scrollView.scrollEnabled = NO;


  当上啦加载下一页的时候执行如下动画并设置childController即可。

1
2
3
4
5
[UIView animateWithDuration:animationDuraion animations:^{
self.scrollView.contentOffset = CGPointMake(0, 2 * kScreenHeight);
} completion:^(BOOL finished) {
self.scrollView.contentOffset = CGPointMake(0, kScreenHeight);
}];

3DTouch

  第一点呢,让cell成为UIViewControllerPreviewing的delegate要用如下方法,并遵守协议UIViewControllerPreviewingDelegate

1
[self registerForPreviewingWithDelegate:cell sourceView:cell.contentView];

  其中cell.contentView是点击之后会出现效果的View,在cell中使用如下方法。

1
- (nullable UIViewController *)previewingContext:(id <UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location;

  在此方法中设置返回你想要的controller即可,此时就可以打开页面了,不过并不能实现在3DTouch呈现半个页面的时候使用其他方法,此时就需要在你返回的Controller方法中实现以下方法

1
2
3
4
5
6
7
- (NSArray<id<UIPreviewActionItem>> *)previewActionItems{
UIPreviewAction *p1 =[UIPreviewAction actionWithTitle:@"分享" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
//在此输入你实现的方法即可
}
NSArray *actions = @[p1];
return actions;
}

  欢迎大家关注我