一、实现效果

通过拖拽屏幕实现卡片移动,左右两侧的卡片随着拖动变小,中间的变大。效果如下:

二、原理说明

1、上面的动画效果是根据余弦函数的曲线特性实现的,先看一下函数曲线y=cos(x),在区间-π/2 到 π/2的范围内,y的值在x的0的是后是最大的,左右则越来越小。

2、可以将被滚动的卡片的高度按照0.0~1.0的比例放大缩小,效果如下:

3、放置到手机屏幕上的效果如下:

三、代码

封装每个卡片为Card.h

卡片显示在CardSwitchView.h上

代码思路是假设控件的中心为原点,中轴线为x轴和y轴,当卡片的中心为距离y轴越近时,卡片长度缩短的比例越趋近1.0,当卡片中线距离y轴越远时,卡片长度缩短的比例越趋近0;

如下图所示假设方块从位置1到位置2向左移动了长度a(写代码时需要做角度和长度的转换),那么在曲线上b的值为cos(a),假设b=0.8,那么就在位置2的时候把高度缩短为原来的0.8倍,以此类推越趋近于控件中轴线的位置卡片越长。(这里角度和长度的转换倍数依情况而定)

//
//  CardSwitchView.m
//  CardSwitchDemo
//
//  Created by Apple on 2016/11/9.
//  Copyright © 2016年 Apple. All rights reserved.
//#import "CardSwitchView.h"
#import "Card.h"//播放器界面的的宽度所占的比例
static float viewScale = 0.70f;@interface CardSwitchView ()<UIScrollViewDelegate>
{//用于切换的ScrollViewUIScrollView *_scrollView;//用于保存各个视图NSMutableArray *_cards;//滚动之前的位置CGFloat _startPointX;//滚动之后的位置CGFloat _endPointX;//需要居中显示的indexNSInteger _currentIndex;
}
@end@implementation CardSwitchView-(instancetype)initWithFrame:(CGRect)frame
{if (self = [super initWithFrame:frame]) {[self buildLayout];}return self;
}-(void)buildLayout
{//初始化ScrollView_scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];_scrollView.delegate = self;_scrollView.showsHorizontalScrollIndicator = false;[self addSubview:_scrollView];//初始化其他参数_cards = [[NSMutableArray alloc] init];_currentIndex = 0;
}#pragma mark -
#pragma mark 视图Frame配置//卡片宽度
-(float)cardWidth
{return viewScale*self.bounds.size.width;
}//卡片间隔
-(float)margin
{return (self.bounds.size.width - [self cardWidth])/4;
}
//卡片起始位置
-(float)startX
{return (self.bounds.size.width - [self cardWidth])/2.0f;
}#pragma mark -
#pragma mark 配置轮播图片
-(void)setCardNumber:(NSInteger)cardNumber
{_cardNumber = cardNumber;//初始化各个播放器位置for (NSInteger i = 0; i<cardNumber; i++ ) {//第一步 在ScrollView上添加卡片float viewX = [self startX] + i*([self cardWidth] + [self margin]);Card* card = [[Card alloc] initWithFrame:CGRectMake(viewX, 0, [self cardWidth], self.bounds.size.height)];card.layer.borderWidth = 1.0f;card.index = i;[_scrollView addSubview:card];[_cards addObject:card];[_scrollView setContentSize:CGSizeMake(card.frame.origin.x + [self cardWidth] + 2*[self margin], 0)];}//更新卡片的大小[self updateCardTransform];
}#pragma mark -
#pragma mark ScrollView代理方法
//开始拖动时保存起始位置
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{_startPointX = scrollView.contentOffset.x;
}//当ScrollView拖动时 变换每个view的大小,并保证居中屏幕的view高度最高
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{[self updateCardTransform];
}//滚动结束,自动回弹到居中卡片
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{//滚动到视图中间位置dispatch_async(dispatch_get_main_queue(), ^{[self scrollToCurrentCard];});
}//卡片自动居中
-(void)scrollToCurrentCard
{_endPointX = _scrollView.contentOffset.x;//设置滚动最小生效范围,滚动超过scrollMiniDistance 即视为有切换卡片的意向float scrollMiniDistance = self.bounds.size.width/30.0f;if (_startPointX - _endPointX > scrollMiniDistance) {NSLog(@"向右滑动屏幕");if (_currentIndex != 0) {_currentIndex -= 1;}}else if (_endPointX - _startPointX  > scrollMiniDistance){NSLog(@"向左滑动屏幕");if (_currentIndex != _cards.count - 1) {_currentIndex += 1;}}float viewX = [self startX] + _currentIndex*([self cardWidth] + [self margin]);float needX = viewX - [self startX];[_scrollView setContentOffset:CGPointMake(needX, 0) animated:true];
}//更新每个卡片的大小
-(void)updateCardTransform
{for (Card *card in _cards) {//获取卡片所在index//获取ScrollView滚动的位置CGFloat scrollOffset = _scrollView.contentOffset.x;//获取卡片中间位置滚动的相对位置CGFloat cardCenterX = card.center.x - scrollOffset;//获取卡片中间位置和父视图中间位置的间距,目标是间距越大卡片越短CGFloat apartLength = fabs(self.bounds.size.width/2.0f - cardCenterX);//移动的距离和屏幕宽度的的比例CGFloat apartScale = apartLength/self.bounds.size.width;//把卡片移动范围固定到 -π/4到 +π/4这一个范围内CGFloat scale = fabs(cos(apartScale * M_PI/4));//设置卡片的缩放card.transform = CGAffineTransformMakeScale(1.0, scale);}
}@end

Demo下载

GitHub项目

iOS 利用余弦函数实现卡片浏览工具相关推荐

  1. iOS 利用UICollectionView横向滚动、余弦函数曲线特性实现居中放大的卡片浏览工具 XLCardSwitch

    一.实现效果 二.原理说明 要实现这样的效果总共分三步:实现横向滚动.居中放大.自动居中.下面就仔细说一下具体的细节: 1.横向滚动 横向滚动是通过UICollectionView的横向滚动特性实现的 ...

  2. ML之MIC:利用有无噪音的正余弦函数理解相关性指标的不同(多图绘制Pearson系数、最大信息系数MIC)

    ML之MIC:利用有无噪音的正余弦函数理解相关性指标的不同(多图绘制Pearson系数.最大信息系数MIC) 目录 利用有无噪音的正余弦函数理解相关性指标的不同(多图绘制Pearson系数.最大信息系 ...

  3. Cooliris – 优雅的照片浏览工具[iOS/Android]

    Cooliris 是一款优雅的照片浏览工具,支持 iOS.Android,还可以将你散落在众多云服务照片集合起来,包括微博.百度云.Instagram 等等.@Appinn 相比于传统的手机相册工具, ...

  4. 利用C语言绘制余弦函数

    绘制余弦曲线 要求:在屏幕上用"*"(星号)显示0°~360°的余弦函数cos(x)曲线.(不使用数组) 问题分析与算法设计 对一般的显示器来说,只能按行输出,即:输出第一行信息后 ...

  5. 【matplotlib库】利用matplotlib库绘制正余弦函数曲线的python程序,标注X、Y轴及标题|CSDN创作打卡

    使用python中的第三方库matplotlib绘制正余弦函数图形,并标注x,y轴以及标题等 ,绘制方法与matlab类似,可以说这里的matplotlib库便是Python中的matlab 程序代码 ...

  6. CSDN论坛浏览工具

    全新设计的CSDN论坛浏览工具,欢迎使用, C++Builder作品,喜欢泡CSDN的朋友,值得一试. 下载地址: http://www.xingzhou.com/cs_setup.exe 文件说明: ...

  7. python绘制条形图用什么函数_Python绘制正余弦函数图像完整代码

    通过python绘制正弦和余弦函数,从默认的设置开始,一步一步地调整改进,让它变得好看,变成我们初高中学习过的图象那样.通过这个过程来学习如何进行对图表的一些元素的进行调整. 01. 简单绘图 mat ...

  8. 余弦函数导数推导过程_人工智能数学基础----导数

    人工智能数学基础----导数 人工智能数学基础系列文章 1. 人工智能数学基础----导数 2. 人工智能数学基础----矩阵 3. 人工智能数学基础----线性二阶近似 人工智能的学习对于数学要求还 ...

  9. 在 Apache Spark 中利用 HyperLogLog 函数实现高级分析

    在 Apache Spark 中利用 HyperLogLog 函数实现高级分析 预聚合是高性能分析中的常用技术,例如,每小时100亿条的网站访问数据可以通过对常用的查询纬度进行聚合,被降低到1000万 ...

最新文章

  1. nvidia share有什么用_NVIDIA共享无法在Win10上运行或响应
  2. 远程桌面linux服务器配置,linux平台下远程桌面服务器的安装和设置
  3. HDU 1430 魔板(康托展开+BFS+预处理)
  4. MySQL 下载与配置教程(免安装版)
  5. getsize java_Java ZipEntry getSize()用法及代码示例
  6. 本地工程提交github
  7. 初二物理模型有哪些_初二是成绩下滑的高危期,做好这5点成绩涨涨涨!(附全学科提升技巧,家长转给孩子!)...
  8. IE8给你选择的理由
  9. Leetcode 279. Perfect Square
  10. mysql创建数据库没有默认值报错_详解Mysql数据库date, datetime类型设置0000-00-00默认值(default)报错问题...
  11. asp.net mysql所有数据库_asp.net 如何获取sql数据库所有列名称
  12. Spring Boot:在Spring Boot中使用定时任务
  13. php preview,preview.php
  14. matlab如何记录时间,求助:在MATLAB里如何输入时间序列中的时间
  15. 【个人】微信小程序初体验
  16. 孩子们各显神通对付 iOS 12「屏幕使用时间」的限制
  17. 在Mac和PC之间共享鼠标键盘(拥有多台电脑者必看)
  18. 数据挖掘 模型的衡量标准与建模
  19. qt程序在win10正常运行win7电脑上崩溃
  20. c语言函数声明大全及详解,C语言之函数的声明详解

热门文章

  1. [转载]Dalvik指令集
  2. 孩子表示法 双亲表示法 孩子兄弟表示法
  3. edgeR、limma、DESeq2三种差异表达包比较(RNA-seq数据)
  4. wacom固件更新错误123,数位板驱动更新不了
  5. 【使用verilog、五级流水和MIPS指令集设计CPU】
  6. 怎么复制 Windows cmd 窗口命令行的信息
  7. EPSON 自学机械手入门记录1(仅供参考)
  8. Flexsim第一周--代码部分学习
  9. 独立产品灵感周刊 DecoHack #20 - 如何停止来自金钱的压力
  10. IPO在即,Uber让你从“拼车”到“拼吃”