内外分离接口依赖及UIScrollView知识点
1:Class Extension 还能巧妙的解决一个接口暴露问题
有些属性或者方法对外可以提供,有些只针对内部的类进行调用;
// Sark.framework/Sark.h
@interface Sark : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *creditCardPassword; // secret!
@end // Sark.framework/PrivateSarkWife.h
@interface PrivateSarkWife : NSObject
- (void)robAllMoneyFromCreditCardOfSark:(Sark *)sark; // needs password!
@end
假设 Sark.h 是 Sark.framework 唯一暴露的 Header,而 framework 中的一个私有类需要获取这个公共类的某个属性(或方法)该怎么办?PrivateSarkWife为Sark.framework内部一个类;上面的 creditCardPassword 属性需要一个对外不可见而对内可见的地方声明,这时候可以利用 Class Extension:
// Sark.h
@interface Sark : NSObject
@property (nonatomic, copy) NSString *name;
@end // Sark+Internal.h <--- new
@interface Sark ()
@property (nonatomic, copy) NSString *creditCardPassword;
@end // Sark.m
#import "Sark.h"
#import "Sark+Internal.h" // <--- new
将对公业务和对私业务用 Class Extension 的形式拆到两个 Header 中,在Sark.m里把两个头文件都进行引用,CreditCardPassword被定义在Sark+Internal.h的头文件里面,这样私有类对私有属性的依赖就被成功隔离开了:
// PrivateSarkWife.m
#import "PrivateSarkWife.h"
#import "Sark+Internal.h" // <--- 私有依赖 @implementation PrivateSarkWife
- (void)robAllMoneyFromCreditCardOfSark:(Sark *)sark {
NSString *password = sark.creditCardPassword; // oh yeah!
}
@end
2:UIScrollView知识点
- (void)viewDidLoad
{
[super viewDidLoad]; scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(, , , )];
scrollView.backgroundColor = [UIColor redColor];
// 是否支持滑动最顶端
// scrollView.scrollsToTop = NO;
scrollView.delegate = self;
// 设置内容大小
scrollView.contentSize = CGSizeMake(, *);
// 是否反弹
// scrollView.bounces = NO;
// 是否分页
// scrollView.pagingEnabled = YES;
// 是否滚动
// scrollView.scrollEnabled = NO;
// scrollView.showsHorizontalScrollIndicator = NO;
// 设置indicator风格
// scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
// 设置内容的边缘和Indicators边缘
// scrollView.contentInset = UIEdgeInsetsMake(0, 50, 50, 0);
// scrollView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 50, 0, 0);
// 提示用户,Indicators flash
[scrollView flashScrollIndicators];
// 是否同时运动,lock
scrollView.directionalLockEnabled = YES;
[self.view addSubview:scrollView]; UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(, , , )];
label.backgroundColor = [UIColor yellowColor];
label.text = @"学习scrolleview";
[scrollView addSubview:label];
[label release];
} #pragma mark -
/*
// 返回一个放大或者缩小的视图
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{ }
// 开始放大或者缩小
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:
(UIView *)view
{ } // 缩放结束时
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
{ } // 视图已经放大或缩小
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
NSLog(@"scrollViewDidScrollToTop");
}
*/ // 是否支持滑动至顶部
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView
{
return YES;
} // 滑动到顶部时调用该方法
- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView
{
NSLog(@"scrollViewDidScrollToTop");
} // scrollView 已经滑动
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
NSLog(@"scrollViewDidScroll");
} // scrollView 开始拖动
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
NSLog(@"scrollViewWillBeginDragging");
} // scrollView 结束拖动
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
NSLog(@"scrollViewDidEndDragging");
} // scrollView 开始减速(以下两个方法注意与以上两个方法加以区别)
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
{
NSLog(@"scrollViewWillBeginDecelerating");
} // scrollview 减速停止
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
NSLog(@"scrollViewDidEndDecelerating");
}
3:仿网易滚动菜单及内容视图滚动效果
#import "NewsViewController.h" #import "VideoViewController.h"
#import "ReaderViewController.h"
#import "ScienceViewController.h"
#import "SocietyViewController.h"
#import "HotViewController.h"
#import "TopLineViewController.h" #import "TitleButton.h" #define ScreenW [UIScreen mainScreen].bounds.size.width
#define ScreenH [UIScreen mainScreen].bounds.size.height @interface NewsViewController ()<UIScrollViewDelegate> @property (nonatomic, strong) UIButton *selButton; @property (nonatomic, strong) NSMutableArray *titleBtns; // 标题滚动view
@property (weak, nonatomic) IBOutlet UIScrollView *titileScrollView; // 内容滚动view
@property (weak, nonatomic) IBOutlet UIScrollView *contentView; @end @implementation NewsViewController - (NSMutableArray *)titleBtns
{
if (_titleBtns == nil) {
_titleBtns = [NSMutableArray array];
}
return _titleBtns;
} // 头条,热点,视频,社会,订阅,科技(science) - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view. // 添加所有子控制器
[self setUpChildViewController]; // 设置标题
[self setUpTitle]; // iOS7之后,导航控制器下所有ScrollView都会添加额外滚动区域
self.automaticallyAdjustsScrollViewInsets = NO; // 初始化scrollView
[self setUpScrollView]; } - (void)setUpScrollView
{
self.titileScrollView.showsHorizontalScrollIndicator = NO; self.contentView.contentSize = CGSizeMake(self.childViewControllers.count * [UIScreen mainScreen].bounds.size.width, ); self.contentView.showsHorizontalScrollIndicator = NO;
self.contentView.pagingEnabled = YES;
self.contentView.bounces = NO; self.contentView.delegate = self;
} - (void)setUpChildViewController
{ TopLineViewController *topLineVc = [[TopLineViewController alloc] init];
topLineVc.title = @"头条";
[self addChildViewController:topLineVc]; HotViewController *hotVc = [[HotViewController alloc] init];
hotVc.title = @"热点";
[self addChildViewController:hotVc]; VideoViewController *videoVc = [[VideoViewController alloc] init];
videoVc.title = @"视频";
[self addChildViewController:videoVc]; SocietyViewController *societyVc = [[SocietyViewController alloc] init];
societyVc.title = @"社会";
[self addChildViewController:societyVc]; ReaderViewController *readerVc = [[ReaderViewController alloc] init];
readerVc.title = @"订阅";
[self addChildViewController:readerVc]; ScienceViewController *scienceVc = [[ScienceViewController alloc] init];
scienceVc.title = @"科技";
[self addChildViewController:scienceVc];
} // 设置标题
- (void)setUpTitle
{
NSUInteger count = self.childViewControllers.count; CGFloat btnX = ;
CGFloat btnY = ;
CGFloat btnW = ;
CGFloat btnH = ; for (NSUInteger i = ; i < count; i++) {
btnX = i * btnW;
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.tag = i;
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
UIViewController *vc = self.childViewControllers[i];
[btn setTitle:vc.title forState:UIControlStateNormal];
[btn setTitleColor:[UIColor redColor] forState:UIControlStateSelected];
btn.frame = CGRectMake(btnX, btnY, btnW, btnH);
[btn addTarget:self action:@selector(titleClick:) forControlEvents:UIControlEventTouchUpInside]; [self.titileScrollView addSubview:btn]; [self.titleBtns addObject:btn];
// 默认选中第一个
if (i == ) {
[self titleClick:btn]; }
} self.titileScrollView.contentSize = CGSizeMake(btnW * count, ); } // 点击标题按钮
- (void)titleClick:(UIButton *)btn
{ // 0.设置标题按钮居中
[self setUpTitleBtnMiddle:btn]; // 1.滚动到对应的界面
CGFloat offsetX = btn.tag * ScreenW; self.contentView.contentOffset = CGPointMake(offsetX, ); // 2.添加对应子控制器view到对应的位置
UIViewController *vc = self.childViewControllers[btn.tag]; vc.view.frame = CGRectMake(offsetX, , ScreenW, self.contentView.bounds.size.height); // NSLog(@"%@",NSStringFromCGRect(self.contentView.bounds));
[self.contentView addSubview:vc.view]; // 还原之前标题的形变
[self setSelectBtn:btn]; } - (void)setSelectBtn:(UIButton *)btn
{
_selButton.transform = CGAffineTransformIdentity;
[_selButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
_selButton.selected = NO; btn.transform = CGAffineTransformMakeScale(1.3, 1.3);
btn.selected = YES; _selButton = btn; } #pragma mark - UIScrollViewDelegate
// 减速完成的时候
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
// 获取当前的偏移量
CGFloat offsetX = scrollView.contentOffset.x;
// 获取页码
int page = offsetX / scrollView.bounds.size.width; UIButton *btn = self.titileScrollView.subviews[page]; // 选中按钮
[self setSelectBtn:btn]; // 设置按钮居中
[self setUpTitleBtnMiddle:btn]; // 添加对应子控制器到界面上
UIViewController *vc = self.childViewControllers[page]; // 已经加载的view就不需要添加了
if (vc.isViewLoaded) return; vc.view.frame = CGRectMake(offsetX , , self.contentView.bounds.size.width, self.contentView.bounds.size.height); [self.contentView addSubview:vc.view];
} // 设置标题按钮居中
- (void)setUpTitleBtnMiddle:(UIButton *)btn
{ // 计算偏移量
CGFloat offsetX = btn.center.x - ScreenW * 0.5; // 左边偏移多了,表示需要往左边看,可视范围往左边,偏移量就减少,最少应该是0
if (offsetX < ) offsetX = ;
CGFloat maxOffsetX = self.titileScrollView.contentSize.width - ScreenW; // 右边偏移多了,表示需要往右边看,可视范围往又边,偏移量就增加,最大不超过内容范围 - 屏幕宽度
if (offsetX > maxOffsetX) offsetX = maxOffsetX; [self.titileScrollView setContentOffset:CGPointMake(offsetX, ) animated:YES]; } // 监听内容view滚动
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat page = scrollView.contentOffset.x / scrollView.bounds.size.width; NSInteger leftIndex = page; // 右边缩放比例
CGFloat rightScale = (page - leftIndex);
// 左边缩放比例
CGFloat leftScale = ( - rightScale); NSInteger rightIndex = leftIndex + ; // 获取左边按钮
TitleButton *leftBtn = self.titleBtns[leftIndex]; NSInteger count = self.titleBtns.count; // 获取右边按钮
TitleButton *rightBtn; if (rightIndex < count) {
rightBtn = self.titleBtns[rightIndex];
} // 设置尺寸
CGFloat leftTransform = leftScale * 0.3 + ; // 1 ~ 1.3
CGFloat rightTransform = rightScale * 0.3 + ; // 1 ~ 1.3
leftBtn.transform = CGAffineTransformMakeScale(leftTransform, leftTransform);
rightBtn.transform = CGAffineTransformMakeScale(rightTransform, rightTransform); // 设置颜色
/*
RGB 红色: 1 0 0
黑色: 0 0 0
*/ UIColor *leftColor = [UIColor colorWithRed:leftScale green: blue: alpha:];
UIColor *rightColor = [UIColor colorWithRed:rightScale green: blue: alpha:]; [leftBtn setTitleColor:leftColor forState:UIControlStateNormal];
[rightBtn setTitleColor:rightColor forState:UIControlStateNormal]; } @end
效果图如下:
内外分离接口依赖及UIScrollView知识点的更多相关文章
- Mock接口依赖的使用
mock 能做什么 1.前后端联调,如果你是一个前端页面开发,现在需要开发一个功能:下一个订单,支付页面的接口,根据支付结果,支付成功,展示支付成功页,支付失败,展示支付失败页.要完成此功能,你需要 ...
- python接口测试中常见的两种接口依赖处理方式
一.请求体的字段依赖 这种情况多数是在当前测试的接口,它的前置接口的请求体中的字段要拿来在当前的接口请求体中继续使用,比如修改用户信息的接口,该接口会使用到用户名的字段,该字段是由创建用户时的请求体中 ...
- Postman实现数字签名,Session依赖, 接口依赖, 异步接口结果轮询
Script(JS)为Postman赋予无限可能 基于Postman 6.1.4 Mac Native版 演示结合user_api_demo实现 PS 最近接到任务, 要把几种基本下单接口调试和持续集 ...
- mock 处理接口依赖
1.输出配置文件如下 login.json [{ "request": { "uri": "/login", "method&qu ...
- Jmeter之接口依赖
一.应用场景 1.现在有两个接口,一个是登录,一个查询,但查询接口必须要依赖登录接口的token,那么通过正则表达式提取器提取登录接口的响应结果 2.现在有两个接口,A接口返回列表数据,另一个查询接口 ...
- 前后端分离&接口API设计学习报告
接口API设计学习报告 15331023 陈康怡 什么是API? API即Application Programming Interface.API是一种通道,负责一个程序与另一个程序的沟通.而对于w ...
- Postman 使用技巧之多环境测试及接口依赖关系处理
一.前言 在日常开发中,除了正常的单元测试,某些情况我们还需要测试 HTTP 接口,团队中目前使用的是「 Postman 」这款 API调试 . HTTP 请求工具.通常我们将经常要测试的接口按照项目 ...
- FastAPI + Vue 前后端分离 接口自动化测试工具 apiAutoTestWeb
apiAutoTestWeb使用说明 apiAutoTestWeb是为apiAutoTest的可视化版本,其采用前后端分离(FastAPI + Vue2)方式实现 具体使用: Python3 + Fa ...
- python使用正则+jsonpath处理接口依赖
1.接口2的入参值依赖接口1的响应结果,如接口2的入参ids需要拿到接口1响应结果的id字段值,测试用例写在excel中,参数:{"ids":"${$..id}$&quo ...
随机推荐
- 如果简单的记录,就可以为这个世界创造更多的财富,那么还有什么理由不去写博客呢? — 读<<黑客与画家>> 有感
上一次博文发文时间是2016.1.15,7个月已经过去了.最近读了一本<>的书,对我触动挺大的!里面有关于技术趋势的探讨,也有关于人生和财富的思考! 开始更新iOS122的文章的初衷是,聚 ...
- 【Android】做一款类似我要当学霸里的学习监督的APP
我要当学霸这款App有个学习监督的功能,当你启动它的时候,你将无法使用其他App,以此达到帮助人提高自觉性,起到监督学习的效果.最近和同学做了个小App,正好有这个功能,所以就来说说它是怎么实现的. ...
- 个人作业-Week2:案例分析
截止时间:2016年9月25日24:00. 很多同学有误解,软件工程课是否就是理论课?或者是几个牛人拼命写代码,其他人打酱油的课?要不然就是学习一个程序语言,搞一个职业培训的课? 都不对, 软件工程有 ...
- QTableWidget控件总结<一>
[1]QTableWidget简介 QTableWidget是QT对话框设计中常用的显示数据表格的控件. 学习QTableWidget就要首先看看QTableView控件(控件也是有"家世& ...
- 使用ViewModel来实现多个Model传送至视图
在开发ASP.NET MVC时,我们会遇上这样的情形,需要一次性传送多个Model从控制器Controller至视图View. 实现很简单,只是创建一个集合类即可. Ok,下面先在数据库准备一些数据, ...
- 使用jquery的append(content)方法的注意事项
append(content)函数:向每个匹配的元素内部追加内容. 如以下示例: 向所有段落中追加一些HTML标记. HTML 代码: <p>I would like to say: &l ...
- Linux下的C编程实战
Linux下的C编程实战(一) ――开发平台搭建 1.引言 Linux操作系统在服务器领域的应用和普及已经有较长的历史,这源于它的开源特点以及其超越Windows的安全性和稳定性.而近年来, Linu ...
- ab网站压力测试
ab网站压力测试命令的参数.输出结果的中文注解 permalink 以前安装好APACHE总是不知道该如何测试APACHE的性能,现在总算找到一个测试工具了.就是APACHE自带的测试工具AB( ...
- MVC - Action和ActionResult
Action 定义在Controller中的Action方法返回ActionResult对象,ActionResult是对Action执行结果的封装,用于最终对请求进行响应.HTTP是一个单纯的采用请 ...
- mvc jquery 修改 viewbag
[HttpGet] public ActionResult Modify(int id) { Books mod=db.Books.Where(b = ...