网易新闻首页骨架(父子控制器实现)

一:父子控制器的应用:效果如图:

二:代码

  1 #import "RHMainViewController.h"
  2 #import "RHNewsTableViewController.h"
  3 #import "RHLable.h"
  4 static const CGFloat lableCount = 8;
  5 static const CGFloat lableWidth = 80;
  6 static const CGFloat lableHeight = 40;
  7 #define SCREENHEIGHT [UIScreen mainScreen].bounds.size.height
  8 #define SCREENWIDTH  [UIScreen mainScreen].bounds.size.width
  9 @interface RHMainViewController ()<UIScrollViewDelegate>
 10 /*顶部标题scrollView*/
 11 @property (nonatomic,weak)UIScrollView *titleScrollView;
 12 /*底部的bottomScrollView*/
 13 @property (nonatomic,weak)UIScrollView *bottomScrollView;
 14 @end
 15
 16 @implementation RHMainViewController
 17
 18 - (void)viewDidLoad {
 19     [super viewDidLoad];
 20
 21     //0:添加子控制器
 22     [self setupChildViewControllers];
 23
 24     //1:创建顶部标题的scrollView
 25     [self setupTopScrollView];
 26
 27     //2:创建底部的scrollView
 28     [self setupBottomScrollView];
 29
 30     //3:默认第一个新闻被选中
 31     [self scrollViewDidEndScrollingAnimation:self.bottomScrollView];
 32 }
 33 - (void)setupTopScrollView {
 34
 35     //1:设置自身属性
 36     self.view.backgroundColor = [UIColor groupTableViewBackgroundColor];
 37     self.title = @"网易";
 38     self.automaticallyAdjustsScrollViewInsets = NO;
 39
 40     //2:创建顶部的标题滚动视图
 41     UIScrollView *titleScroll = [[UIScrollView alloc]init];
 42     titleScroll.frame = CGRectMake(0, 64, self.view.frame.size.width, 40);
 43     titleScroll.showsVerticalScrollIndicator = NO;
 44     titleScroll.showsHorizontalScrollIndicator = NO;
 45     titleScroll.bounces = NO;
 46     self.titleScrollView = titleScroll;
 47     [self.view addSubview:titleScroll];
 48
 49     //3:创建顶部scrollView上的按钮
 50     for (int i = 0; i <lableCount; i++) {
 51
 52         RHLable *lable = [[RHLable alloc]init];
 53         lable.frame = CGRectMake(i *lableWidth, 0, lableWidth, lableHeight);
 54         [lable addGestureRecognizer:  [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapAction:)]];
 55         lable.text = [self.childViewControllers[i] title];
 56         lable.tag = i;
 57         [titleScroll addSubview:lable];
 58         if (i == 0) {
 59             lable.sca = 1;
 60         }
 61     }
 62
 63     titleScroll.contentSize = CGSizeMake(lableCount *lableWidth, 0);
 64
 65
 66 }
 67 - (void)setupBottomScrollView {
 68
 69     //1:创建底部的scrollView
 70     UIScrollView *bottomScrollView = [[UIScrollView alloc]init];
 71     bottomScrollView.frame = CGRectMake(0,CGRectGetMaxY(self.titleScrollView.frame) ,SCREENWIDTH , SCREENHEIGHT - 64 - 40);
 72     bottomScrollView.bounces = NO;
 73     bottomScrollView.showsVerticalScrollIndicator = NO;
 74     bottomScrollView.showsHorizontalScrollIndicator = NO;
 75     bottomScrollView.pagingEnabled = YES;
 76     bottomScrollView.contentSize = CGSizeMake(lableCount *SCREENWIDTH, 0);
 77     self.bottomScrollView = bottomScrollView;
 78     bottomScrollView.delegate = self;
 79     [self.view addSubview:bottomScrollView];
 80
 81 }
 82
 83 - (void)setupChildViewControllers {
 84
 85     //新闻
 86     RHNewsTableViewController *news = [[RHNewsTableViewController alloc]init];
 87     news.title = @"新闻";
 88     [self addChildViewController:news];
 89
 90     //历史
 91     RHNewsTableViewController *history = [[RHNewsTableViewController alloc]init];
 92     history.title = @"历史";
 93     [self addChildViewController:history];
 94
 95     //阅读
 96     RHNewsTableViewController *read = [[RHNewsTableViewController alloc]init];
 97     read.title = @"阅读";
 98     [self addChildViewController:read];
 99
100     //视频
101     RHNewsTableViewController *video = [[RHNewsTableViewController alloc]init];
102     video.title = @"视频";
103     [self addChildViewController:video];
104
105     //图片
106     RHNewsTableViewController *image = [[RHNewsTableViewController alloc]init];
107     image.title = @"图片";
108     [self addChildViewController:image];
109
110     //朋友
111     RHNewsTableViewController *friend = [[RHNewsTableViewController alloc]init];
112     friend.title = @"朋友";
113     [self addChildViewController:friend];
114
115     //问答
116     RHNewsTableViewController *answer = [[RHNewsTableViewController alloc]init];
117     answer.title = @"问答";
118     [self addChildViewController:answer];
119
120     //知识
121     RHNewsTableViewController *know = [[RHNewsTableViewController alloc]init];
122     know.title = @"知识";
123     [self addChildViewController:know];
124
125 }
126 - (void)tapAction:(UITapGestureRecognizer*)tap {
127
128     //1:切换底部的scrollView的视图
129      NSUInteger index = tap.view.tag;
130     [self.bottomScrollView setContentOffset:CGPointMake(index *SCREENWIDTH, 0) animated:YES];
131
132 }
133 /**
134  * scrollView结束了滚动动画以后就会调用这个方法(比如- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated;方法执行的动画完毕后)
135  */
136 - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
137
138     NSInteger index = scrollView.contentOffset.x / SCREENWIDTH;
139     RHLable *currentLable = self.titleScrollView.subviews[index];
140
141     //1:当点击lable时,先将点击的lable自身居中
142     CGFloat moveX = currentLable.center.x - SCREENWIDTH *0.5;
143     CGFloat offset = self.titleScrollView.contentSize.width - SCREENWIDTH;
144     if (moveX < 0)   moveX = 0;
145     if (moveX > offset)  moveX = offset;
146
147     [self.titleScrollView setContentOffset:CGPointMake(moveX, 0) animated:YES];
148
149     //2:设置其他lable为正常比例
150     for (RHLable *lable in self.titleScrollView.subviews) {
151         if (lable != currentLable) lable.sca = 0.0;
152
153     }
154
155     UIViewController *new = self.childViewControllers[index];
156     //如果控制器的view已经加载过了,直接返回
157     if ([new isViewLoaded]) return;
158     new.view.frame = CGRectMake(index *SCREENWIDTH, 0, SCREENWIDTH, self.bottomScrollView.frame.size.height);
159     [self.bottomScrollView addSubview:new.view];
160
161 }
162 /**
163  * 只要scrollView在滚动,就会调用
164  */
165 - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
166
167    CGFloat scale = scrollView.contentOffset.x / SCREENWIDTH;
168   if (scale < 0 || scale > self.childViewControllers.count -1) return;
169    NSInteger leftIndex = scale;//将浮点型数转换为整数,小数无论多少全部去掉
170    NSInteger rightIndex = leftIndex + 1;
171
172   //左侧的lable
173     RHLable *leftLable = self.titleScrollView.subviews[leftIndex];
174
175   //右侧的lable
176     RHLable *rightLable = (rightIndex == self.titleScrollView.subviews.count) ? nil :  self.titleScrollView.subviews[rightIndex];
177
178     CGFloat rightScale = scale - leftIndex;
179     CGFloat leftScale = 1 - rightScale;
180
181     leftLable.sca = leftScale;
182     rightLable.sca = rightScale;
183
184 }
185 /**
186  * 手指松开scrollView后,scrollView停止减速完毕就会调用这个
187  */
188 - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
189
190     [self scrollViewDidEndScrollingAnimation:scrollView];
191 }
192
193 @end
 1 #import "RHNewsTableViewController.h"
 2 static NSString *const cellID = @"ID";
 3 @interface RHNewsTableViewController ()
 4
 5 @end
 6
 7 @implementation RHNewsTableViewController
 8
 9 - (void)viewDidLoad {
10     [super viewDidLoad];
11
12     [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellID];
13
14 }
15
16
17 #pragma mark - Table view data source
18
19 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
20
21     return 1;
22 }
23
24 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
25
26     return 30;
27 }
28
29
30 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
31     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID forIndexPath:indexPath];
32     cell.textLabel.text = [NSString stringWithFormat:@"%ld--------%@",(long)indexPath.row,self.title];
33     return cell;
34 }
35
36 @end
1 #import <UIKit/UIKit.h>
2
3 @interface RHLable : UILabel
4 + (instancetype)lable;
5 @property (nonatomic,assign)CGFloat sca;
6 @end
 1 #import "RHLable.h"
 2 //247 86 176
 3 @implementation RHLable
 4
 5 + (instancetype)lable {
 6
 7     return [[self alloc]init];
 8 }
 9
10 - (instancetype)initWithFrame:(CGRect)frame {
11
12     if (self = [super initWithFrame:frame]) {
13
14        //1:设置自身的属性
15         self.font = [UIFont systemFontOfSize:15];
16         self.textAlignment = NSTextAlignmentCenter;
17         self.textColor = [UIColor colorWithRed:RHRed green:RHGreen blue:RHBlue alpha:1];
18         self.userInteractionEnabled = YES;
19     }
20
21     return self;
22 }
23
24 - (void)setSca:(CGFloat)sca {
25
26     _sca = sca;
27
28     // R G B
29     // 默认:0.4 0.6 0.7
30     // 红色:1   0   0
31
32     CGFloat redScale = RHRed + (1 - RHRed) *sca;
33     CGFloat greenScale = RHGreen - RHGreen *sca;
34     CGFloat blueScale = RHBlue - RHBlue *sca;
35
36     self.textColor = [UIColor colorWithRed:redScale green:greenScale blue:blueScale alpha:1];
37     CGFloat fontScale = 1 +sca *0.3;
38     self.transform = CGAffineTransformMakeScale(fontScale, fontScale);
39
40 }
41
42 @end
#import<UIKit/UIKit.h>

UIKIT_EXTERN const  CGFloat RHRed;
UIKIT_EXTERN const  CGFloat RHGreen;
UIKIT_EXTERN const  CGFloat RHBlue;
UIKIT_EXTERN const  int Age;
UIKIT_EXTERN NSString *const Name;
1 #import <UIKit/UIKit.h>
2
3 const CGFloat RHRed = 0.4;
4 const CGFloat RHGreen = 0.6;
5 const CGFloat RHBlue = 0.7;
6 const int Age = 10;
7 NSString *const Name = @"刚刚好";

三:知识点总结:

1:用static const定义基本数据,或是字符串来代替宏定义来节省内存 ,利用父子控制器,先将子控制器添加到父控制器上,此时父控制器最子控制器有一个强引用,只要父控制器在,则子控制器就会存在,不会销毁。子控制器在,子控制器就会对其上的view有一个强引用,子控制器View就不会销毁

2:当有导航栏的时候,又有scrollView或是继承scrollView的子控件如tableView或是collecttionView,系统会自动为滚动视图增加额外的64滚动区域,解决可以采取两种方法:1:self.automaticallyAdjustsScrollViewInsets = NO;默认为YES,自动调整 2:设置contentInset属性,减少其额外的滚动区域。

3:scrollView设置:titleScroll.showsVerticalScrollIndicator = NO; titleScroll.showsHorizontalScrollIndicator = NO设置隐藏两个滚动条后,则scrollView的子控件中就没有了这两个子控件,就同UIView,可以用scrollView.subViews,得到添加到scrollView上的子控件。其中属性用weak修饰,但是依然对象没有销毁,是因为该view添加到了self.view上了,则self.view对该scrollView有一个强引用,所以其对象不会销毁

4: lable.text = [self.childViewControllers[i] title];不用再去定义数组装着标题,去设置lable的text,任何属性都会生成下划线的成员变量,set和get方法,set方法赋完值后,若想在其他方法中获得该值,则可调用其属性的get方法。

5:scrollView不能滚动:1:scrollView.enablescroll  2:没有设置scrollView的contentSize 3:

setContentOffset animated 该方法设置scrollView的偏移量,自动产生动画,不用再去搞UIView的动画 4:NSInteger:整数,去除小数点。NSUinteger,修饰的数是大于等于0的。

6:scrollView的代理方法:1:scrollViewDidScroll:监听滚动,实时调用 2:scrollViewDidEndDecelerating:减速停止方法,当手指松开的时候调用 3:

scrollViewDidEndScrollingAnimation 当scrollView所有滚动动画停止的时候调用

7:网易首页骨架的实现思路:1:利用父子控制器,先添加子控制器到父控制器中 2:分别创建titleScrollView和bottomScrollView,并为titleScrollView添加手势,为bottomScrollView设置代理,当点击顶部的滚动视图时,点击的标题居中,切换底部的视图,通过tap.view.tag;可获得点击lable的index,也就是底部滚动视图所需要偏移的位置。用setContentOffset animated,实现底部滚动视图的动画偏移,在滚动视图动画停止的代理方法中scrollViewDidEndScrollingAnimation,设置点击lable的自身居中显示,用点击lable的自身中心点x与屏幕中心点x作比较,小于0.则不让其偏移,若是大于顶部滚动视图的最大偏移量(contentSize.width - SCREENWIDTH),则让其偏移量为最大偏移量。改变自身居中显示后,还要偏移底部滚动视图,需要将底部相应控制器的从父控制器的数组中取出,将view添加到底部的scrollView上,此时要加判断, if ([newVC isViewLoaded]) return;如果子控制器已经加载过了,就返回,避免重复添加view。3:当滚动底部的滚动视图时,顶部的滚动视图也要同步显示,在减速停止方法中,再调用scrollViewDidEndScrollingAnimation即可 4:监听scrollView的实时滚动,从而设置lable的颜色和字体变化,先通过偏移量求出scrollView偏移到第几页CGFloat类型,再做条件过滤,如果if (scale < 0 || scale > self.childViewControllers.count -1) return;偏移的第几页也有可能出现负数,或是大于子控件个数。(其实也可以不去设置此过滤条件)第二个限制条件,不能用scrollView.subViews.count,原因是控制器的view是懒加载的,当滚动时,此时view还没有添加到scrollView上。左右滑动时,求出左右的index,从顶部滚动视图的子控件数组中取出lable,求出左右lable的比例,赋值给lable,重写lable比例的set方法,颜色的改变,按比例值改变,在原来颜色的比例上,增加或是减少。字体的变大,可以设置lable自身transform按比例进行缩放,比例值计算,在1的基础上加上按比例计算的缩放值。5:在didscrollView执行完毕后后,又会调用scrollViewDidEndScrollingAnimation,在此方法中,遍历顶部滚动视图的子控件,让别的lable恢复比例的默认值。6:设置默认新闻被选中,则相当于调用了scrollViewDidEndScrollingAnimation方法,并且在创建lable时,默认i==0时,设置比例值为1

8:全局常量的设置:定义头文件,在创建相同类名空文件作为.m文件,.m文件负责定义常量,.h负责extern引用常量。

9:注册tableView的表格,就不用再去判断创建cell了,在数据源方法中,直接从缓存池中取可重用cell就可以了, [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellID];

时间: 2025-01-02 00:34:44

网易新闻首页骨架(父子控制器实现)的相关文章

iOS 网易新闻首页进化版Demo(MXSegmentedPager),自带平行头部拉伸

网易新闻首页类似的界面简直太常见了,需求不同自然做出来的效果不同了,之前 用ScrollView写过一个控制器的封装,但是这里根本没有考虑到控制器的复用以及预加 载机制,如果没考虑复用的话当界面爆炸的时候估计你的App会很卡,例如半塘这样 的,我抓包发现貌似会预加载当前界面后三个界面,让用户滑动的时候能第一时间看到 数据,这样的机制蛮不错的,今天来介绍个能复用的框架,顺带介绍个另一个高斯模糊 的Catagory. 上图 这里的三个界面分别是最普通的控制器,webview以及双TableView

网易新闻首页iOS

// //  ViewController.m //  wyy // //  Copyright © 2016年 zm. All rights reserved. // #import "ViewController.h" #import "ZMViewController.h" #import "ZMLabel.h" @interface ViewController ()<UIScrollViewDelegate> @proper

iOS实现网易新闻首页

主要就是这个页面,实现的主要功能有:1.点击上面的标题栏,下方的红色滚动条跟着到所点击的标题的下方;2中间的图片进行循环自动播放;3,点击下面的各项标签将所点击的标签添加到上面的标题栏,4当点击下面的标签在上面已经存在的时候将其从上面的标题栏移除 //viewDidLoad里面调用各种方法 - (void)viewDidLoad { // Do any additional setup after loading the view. self.titleArray = [NSMutableArr

android 仿网易新闻首页框架

   首页布局: 1 SliddingMenu  +  ViewPagerIndicator 2 JSON 解析   FastJson 3 网络请求  Volley 4 sqlite 数据库简单封装,主要处理数据库版本升级问题 5 微信.微博 API 简单封装 6 代码混淆 ...... github: https://github.com/lesliebeijing/MyAndroidFramework.git

IOS 类似于网易新闻首页新闻轮播的组件

一.需求分析 1.可横向循环滚动新闻图片 2.滚动到对应图片时显示新闻标题 3.每张新闻图片可点击 4.有pageControl提示 5.具有控件的扩展能力 二.设计实现 1.显示图片使用SDWebImage第三方库,可缓存图片.通过url异步加载图片 2.使用一个横向滚动的UITableView实现循环滚动 3.使用一个黑色半透明的背景.白色文字的UILabel显示标题 4.定义每个新闻的数据结构: /** @brief 默认使用本地地址,如果本地没有的话,使用网络图片 */ @interfa

ActionBar+DrawerLayout实现网易新闻客户端首页

一.概述 随着android版本的不断的更新,google推出了越来越多的高级组件,采用这些官方组件我们可以方便的实现一些以前需要通过复杂编码或者使用第三方组件才能实现的效果,比如slidingmenu.sherlockactionbar等.在这里,我们通过使用android的官方组件ActionBar和DrawerLayout来实现网易新闻客户端首页的效果. 由于ActionBar和DrawerLayout都是后来推出的,如果需要兼容低版本必须在项目中添加v7支持库.具体如何添加支持库在此不做

新版网易新闻客户端应用源码

源码下载: http://code.662p.com/view/11510.html 演示图:   1.这次更新的亮点是添加了天气效果以后也可以用网易新闻看天气预报了,各种轻微的 动画效果也没有放过. 2.新版的网易新闻,整改了首页UI,在底部加上了tabbar,因此多了很多页面这里也都编了,但是无法交互.毕竟东西太多了,我觉得能点击看到效果就算不能进一步深入,就一个壳子也比全空没有强是吧.. 3.主页-主页的下方加了tabbar,nav的两个 按钮做了改变 4.详情页-详情页对细节的处理更加注

新版网易新闻客户端应用iOS源码

这是一个不错的iOS项目源码. 源码下载: http://code.662p.com/view/11510.html 演示图:   1.这次更新的亮点是添加了天气效果以后也可以用网易新闻看天气预报了,各种轻微的动画效果也没有放过. 2.新版的网易新闻,整改了首页UI,在底部加上了tabbar,因此多了很多页面这里也都编了,但是无法交互.毕竟东西太多了,我觉得能点击看到效果就算不能进一步深入,就一个壳子也比全空没有强是吧.. 3.主页-主页的下方加了tabbar,nav的两个按钮做了改变 4.详情

网易新闻部分框架

一 网易功能图 二 需要解决的问题 1> 搭建界面,设置标题 2> 处理标题按钮点击事件,处理常见的bug 3> 监听内容的滚动 4> 滚动范围的判断 5> 字体大小和颜色的渐变 三 内容显示和标题显示搭建 1 思路: 由总体app的效果,我们可以看出,标题和内容界面都是可以滚动的,而且标题还可以点击 2 具体方案:采用两个UIScrollView来实现. 3 显示内容的代码: #pragma mark - 创建控制器内容的scrollView - (void)setUpCh