我的编程空间,编程开发者的网络收藏夹
学习永远不晚

iOS使用UICollectionView实现横向滚动照片效果

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

iOS使用UICollectionView实现横向滚动照片效果

本文实例为大家分享了iOS使用UICollectionView实现横向滚动展示照片的具体代码,供大家参考,具体内容如下

这是Demo链接

效果图

思路

1. 界面搭建

界面的搭建十分简单,采用UICollectionView和自定义cell进行搭建即可。


// ViewController.m

// 下面使用到的宏和全局变量
#define ScreenW [UIScreen mainScreen].bounds.size.width
#define ScreenH [UIScreen mainScreen].bounds.size.height
static NSString *const cellID = @"cellID";

// 创建collectionView的代码
- (void)setupCollectionView
{
 // 使用系统自带的流布局(继承自UICollectionViewLayout)
 UICollectionViewFlowLayout *layout = ({
 UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
 // 每个cell的大小
 layout.itemSize   = CGSizeMake(180, 180);
 // 横向滚动
 layout.scrollDirection  = UICollectionViewScrollDirectionHorizontal;
 // cell间的间距
 layout.minimumLineSpacing  = 40;

 //第一个cell和最后一个cell居中显示(这里我的Demo里忘记改了我用的是160,最后微调数据cell的大小是180)
 CGFloat margin = (ScreenW - 180) * 0.5;
 layout.sectionInset  = UIEdgeInsetsMake(0, margin, 0, margin);

 layout;
 });

 // 使用UICollectionView必须设置UICollectionViewLayout属性
 UICollectionView *collectionView = ({
 UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
 collectionView.center  = self.view.center;
 collectionView.bounds  = CGRectMake(0, 0, ScreenW, 200);
 collectionView.backgroundColor = [UIColor brownColor];
 // 这里千万记得在interface哪里写<UICollectionViewDataSource>!!!
 collectionView.dataSource = self;
 [collectionView setShowsHorizontalScrollIndicator:NO];

 [self.view addSubview:collectionView];

 collectionView;
 });

 // 实现注册cell,其中PhotoCell是我自定义的cell,继承自UICollectionViewCell
 UINib *collectionNib = [UINib nibWithNibName:NSStringFromClass([PhotoCell class])
      bundle:nil];
 [collectionView registerNib:collectionNib
 forCellWithReuseIdentifier:cellID];
}

// UICollectionViewCellDataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView
 numberOfItemsInSection:(NSInteger)section
{
 return 10;
}

- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
    cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
 PhotoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellID 
    forIndexPath:indexPath];

 // 图片名是 0 ~ 9
 cell.imageName = [NSString stringWithFormat:@"%ld", (long)indexPath.row];

 return cell;
}

// 界面是一个xib文件,在cell里拖了个ImageView,约束上下左右都是10
// 图片名是数字 0 ~ 9

// PhotoCell.h
@property (nonatomic, strong) NSString *imageName;

// PhotoCell.m
@interface PhotoCell ()

@property (weak, nonatomic) IBOutlet UIImageView *imageView;

@end

@implementation PhotoCell

- (void)awakeFromNib {
 [super awakeFromNib];
 // Initialization code
}

- (void)setImageName:(NSString *)imageName
{
 _imageName = imageName;

 self.imageView.image = [UIImage imageNamed:imageName];
}

到这里最基础的效果就实现完了,一组大小相等的图片cell。

2.大小变化已经居中效果实现

由于系统的UICollectionViewFlowLayout无法实现我想要的效果,因此我重写下该类中的某些方法。 在UICollectionViewLayout中有这样两句注释:

Methods in this class are meant to be overridden and will be called by its collection view to gather layout information. 在这个类中的方法意味着被重写(overridden),并且将要被它的 collection view 调用,用于收集布局信息

To get the truth on the current state of the collection view, call methods on UICollectionView rather than these. 要获取 collection view 的当前状态的真相,调用UICollectionView上的方法,而不是这些 其中有一点需要解释下,collectionView的bounds的x和y实际上就是collectionView的内容视图的 x和y。关于这点,请看我写的一篇博文的解释:iOS bounds学习笔记以及仿写UIScrollView的部分功能


// MyFlowLayout.h
#import <UIKit/UIKit.h>

// 注意!继承自UICollectionViewFlowLayout,因为它继承自UICollectionViewLayout。
@interface TWLayout : UICollectionViewFlowLayout

// MyFlowLayout.m

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
 return YES;
}



- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
 // 获取collectionView的宽带
 CGFloat collectionW = self.collectionView.bounds.size.width;

 // 获取布局属性数组
 NSArray<UICollectionViewLayoutAttributes *> *attrs = [super layoutAttributesForElementsInRect:self.collectionView.bounds];
 for (int i = 0; i < attrs.count; i++) {
 UICollectionViewLayoutAttributes *attr = attrs[i];

 //每个显示的cell距离中心距离
 CGFloat margin = fabs((attr.center.x - self.collectionView.contentOffset.x) - collectionW * 0.5);

 // 缩放比例:(margin / (collectionW * 0.5))得出的结论相当于 0 ~ 1。而我们需要它的缩放比例是 1 ~ 0.65,这样就是 (1 - 0)~(1 - 0.35)
 CGFloat scale = 1 - (margin / (collectionW * 0.5)) * 0.35;

 attr.transform = CGAffineTransformMakeScale(scale, scale);
 }

 return attrs;
}



- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
 // 获取collectionView的宽度
 CGFloat collectionW = self.collectionView.bounds.size.width;
 // 获取当前的内容偏移量
 CGPoint targetP = proposedContentOffset;

 // 获取显示cell的布局属性数组,横向滚动,所以只用考虑横向的x和width,纵向不用考虑
 NSArray *attrs = [super layoutAttributesForElementsInRect:CGRectMake(targetP.x, 0, collectionW, MAXFLOAT)];

 // 距离中心点最近的cell的间距(中间那个cell距离最近,值可正可负)
 CGFloat minSpacing = MAXFLOAT;
 for (UICollectionViewLayoutAttributes *attr in attrs) {
 // 距离中心点的偏移量
 CGFloat centerOffsetX = attr.center.x - targetP.x - collectionW * 0.5;
 // fabs():CGFloat绝对值
 if (fabs(centerOffsetX) < fabs(minSpacing)) {
  minSpacing = centerOffsetX;
 }
 }
 targetP.x += minSpacing;

 return targetP;
}

最后,记得把 UICollectionViewFlowLayout 改成你自定义的FlowLayout对象!!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

iOS使用UICollectionView实现横向滚动照片效果

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

iOS使用UICollectionView实现横向滚动照片效果

本文实例为大家分享了iOS使用UICollectionView实现横向滚动展示照片的具体代码,供大家参考,具体内容如下 这是Demo链接 效果图思路 1. 界面搭建 界面的搭建十分简单,采用UICollectionView和自定义cell进
2022-05-28

ios uicollectionview实现横向滚动

现在使用卡片效果的app很多,之前公司让实现一种卡片效果,就写了一篇关于实现卡片的文章。文章最后附有demo 实现上我选择了使用UICollectionView ;用UICollectionViewFlowLayout来定制样式;下面看看具
2022-05-31

iOS实现卡片式滚动效果 iOS实现电影选片效果

本文实例为大家分享了iOS实现卡片式滚动效果的具体代码,供大家参考,具体内容如下 先来张效果图吧:直接上源码了: CardScrollView.h#import @interface CardView : UI
2022-06-01

Vue怎么实现超出宽度文字横向滚动效果

今天小编给大家分享一下Vue怎么实现超出宽度文字横向滚动效果的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、npm 安装如
2023-07-04

Vue如何实现类似头条效果的横向滚动导航条

这篇文章主要讲解了“Vue如何实现类似头条效果的横向滚动导航条”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Vue如何实现类似头条效果的横向滚动导航条”吧!  cube-ui 所提供的组件中
2023-07-04

怎么在vue中使用better-scroll实现横向滚动

本篇文章为大家展示了怎么在vue中使用better-scroll实现横向滚动,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。一、滚动的实现原理better-scroll的滚动原理和浏览器原生滚动原理是
2023-06-15

怎么用JavaScript实现图片循环滚动效果

要实现图片循环滚动效果,可以通过JavaScript结合CSS实现。下面是一个简单的示例:HTML部分:
怎么用JavaScript实现图片循环滚动效果
2024-03-02

怎么在Vue中使用better-scroll组件实现横向滚动功能

怎么在Vue中使用better-scroll组件实现横向滚动功能?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。一、滚动的实现原理better-scroll的滚动
2023-06-15

vue怎么使用动画实现滚动表格效果

这篇文章主要介绍“vue怎么使用动画实现滚动表格效果”,在日常操作中,相信很多人在vue怎么使用动画实现滚动表格效果问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”vue怎么使用动画实现滚动表格效果”的疑惑有所
2023-06-29

怎么使用C# WPF实现动态3D光照效果

这篇文章主要介绍“怎么使用C# WPF实现动态3D光照效果”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么使用C# WPF实现动态3D光照效果”文章能帮助大家解决问题。交互式调节光效接下来想动态实
2023-07-05

Android 使用CoordinatorLayout实现滚动标题栏效果的实例

在Material Design里,CoordinatorLayout通常用来作为顶层视图,来协调处理各个子View之间的动作,从而实现各种动画效果,如Snackbar与FloatingActionButton的配合显示效果,就是以Coor
2022-06-06

Android中怎么使用ListView实现滚轮动画效果

今天就跟大家聊聊有关Android中怎么使用ListView实现滚轮动画效果,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。 private
2023-05-31

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录