CollectionView实现图片无限切换

一.说明:

新建一个Single View Application,删除main.stroryboard中原有的控制器,拖入一个新的CollectionViewController;

在原有的ViewController.h文件中,将继承改成UICollectionViewController,且绑定CollectionViewController

要使用原型cell来创建每张图片,故建立相应的cell文件并绑定.在原型cell中拖入一张imageView,并设定其约束覆盖全cell

在Assets.xcassets中拖入图片,至此基本界面搭建完毕.

二.实现代码:

//
//  HBImageCell.h文件
//  4.30 图片轮播

#import <UIKit/UIKit.h>

@interface HBImageCell : UICollectionViewCell
//创建一个imgName属性,当导入imgName时,为图像赋值
@property (nonatomic,copy)NSString *imgName;
@end

设置cell中图片的Outlets接口

//
//  HBImageCell.m文件
//  4.30 图片轮播

#import "HBImageCell.h"
@interface HBImageCell ()
@property (weak, nonatomic) IBOutlet UIImageView *imgView;
@end

@implementation HBImageCell
-(void)setImgName:(NSString *)imgName{
    _imgName = imgName;
    UIImage *img = [UIImage imageNamed:imgName];
    self.imgView.image = img;
}

@end
/*  ViewController.m文件中
 思想:为了使图片能无限轮播,将图片每次的位置都滚动到第2位,且设立个新索引,图片内容根据新索引变化
 */

#import "ViewController.h"
#import "HBImageCell.h"
//将图片数量定义为宏,方便后期维护
#define IMG_COUNT 9
@interface ViewController ()
//拖入layout的输出接口
@property (weak, nonatomic) IBOutlet UICollectionViewFlowLayout *flowLayout;
@property (assign,nonatomic)int index;
@end

@implementation ViewController
//在main.storyboard的cell中也应设定相同的可重用identifier
static NSString *ID = @"IMG";

#pragma mark - ViewDidLoad
- (void)viewDidLoad {
    [super viewDidLoad];
    //使每个单元格的尺寸与屏幕相同
    self.flowLayout.itemSize = self.view.frame.size;
    //设置单元格之间的间隙为0
    self.flowLayout.minimumLineSpacing = 0;
    //设置滚动方式为水平滚动
    self.flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    //隐藏水平滚动条
    self.collectionView.showsHorizontalScrollIndicator = NO;
    //设置分页显示
    self.collectionView.pagingEnabled = YES;
    //刚开始就将其滚动到第2个位置
    [self scrollToSecondPosition];
}
#pragma mark - 返回个数
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return IMG_COUNT;
}
#pragma mark - 返回内容
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    //取出原型cell
    HBImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];

    //要先判断是向左拖还是向右拖,在拖动时就显示图片内容
    //但不能直接在self.index上改动,否则在拖动结束后index还会自增(自减),故建立一个临时变量
    int tempIndex = self.index;
    if (indexPath.item == 0) {
        tempIndex --;
    }else if (indexPath.item == 2){
        tempIndex ++;
    }
    //判断越界
    if (tempIndex == IMG_COUNT) {
        tempIndex = 0;
    }else if (tempIndex == -1){
        tempIndex = IMG_COUNT - 1;
    }

    //为cell赋imgName
    NSString *imgName = [NSString stringWithFormat:@"%zd",tempIndex];
    cell.imgName = imgName;

    return cell;
}

#pragma mark - 拖动结束时调用
//通过该方法来确定图片最后显示的内容
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    //通过偏移来得知是向左还是向右拖动
    CGFloat offset = scrollView.contentOffset.x;
    int next = offset/self.flowLayout.itemSize.width;
    if (next == 0) {
        self.index--;
    }else if (next == 2){
        self.index++;
    }
    //越界判断
    if (self.index == IMG_COUNT) {
        self.index = 0;
    }else if (self.index == -1){
        self.index = IMG_COUNT - 1;
    }

    //加入异步线程,回到第2个位置
    dispatch_async(dispatch_get_main_queue(), ^{
        [self scrollToSecondPosition];
    });

}

#pragma mark - 滚动到第二个的位置方法
-(void)scrollToSecondPosition{
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:1 inSection:0];
    [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionNone animated:NO];

}
@end

至此实现代码完成.

三.优化

图片的索引变化和判断越界可使用一句优化算法代替

/*
    ViewController.m文件中
 */

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    ....
    int tempIndex = self.index;
    if (indexPath.item == 0) {
        tempIndex --;
    }else if (indexPath.item == 2){
        tempIndex ++;
    }
    //判断越界
    if (tempIndex == IMG_COUNT) {
        tempIndex = 0;
    }else if (tempIndex == -1){
        tempIndex = IMG_COUNT - 1;
    }
    tempIndex = (tempIndex + (indexPath.item -1))%IMG_COUNT;
    ....
}

#pragma mark - 拖动结束时调用
//通过该方法来确定图片最后显示的内容
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    //通过偏移来得知是向左还是向右拖动
    CGFloat offset = scrollView.contentOffset.x;
    int next = offset/self.flowLayout.itemSize.width;
    if (next == 0) {
        self.index--;
    }else if (next == 2){
        self.index++;
    }
    //越界判断
    if (self.index == IMG_COUNT) {
        self.index = 0;
    }else if (self.index == -1){
        self.index = IMG_COUNT - 1;
    }
    self.index = (self.index + (next - 1))%IMG_COUNT;
   ...
}

四.注意点

    HBImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];

从原型cell中取得cell不需要注册,而使用xib或class文件中获得cell则要在viewDidLoad中注册相应的cell

    //注册nib
    [self.collectionView registerNib:<#(nullable UINib *)#> forCellWithReuseIdentifier:<#(nonnull NSString *)#>]
    //注册class
    [self.collectionView registerClass:<#(nullable Class)#> forCellWithReuseIdentifier:<#(nonnull NSString *)#>]
时间: 2024-12-14 05:27:24

CollectionView实现图片无限切换的相关文章

iOS开发之ImageView复用实现图片无限轮播

在上篇博客中iOS开发之多图片无缝滚动组件封装与使用给出了图片无限轮播的实现方案之一,下面在给出另一种解决方案.今天博客中要说的就是在ScrollView上贴两个ImageView, 把ImageView进行交替切换来实现图片的无限轮播,在轮播时去修改ImageView上的图片.上一篇博客中是有几张图片就实例化几个ImageView, 然后事先把Image贴到相应的ImageView上,这种做法比较简单,而且易于实现. 今天这篇博客就要实现使用两张ImageView, 交替的区展示Image,

Swift - 使用CollectionView实现图片Gallery画廊效果(左右滑动浏览图片)

1,效果图 (1)图片从左至右横向排列(只有一行),通过手指拖动可以前后浏览图片. (2)视图滚动时,每张图片根据其与屏幕中心距离的不同,显示尺寸也会相应地变化.越靠近屏幕中心尺寸就越大,远离屏幕中心的就逐渐变小. (3)滑动结束后,会有位置自动修正的功能.即将当前最靠近屏幕中点的图片移动到正中央. (4)点击图片则将该图片删除,点击空白处会在最开始的位置插入一张图片.不管新增还是删除都有动画效果. (5)点击导航栏上的"切换"按钮,可以在普通的流式布局和我们自定义的画廊布局间相互切换

利用jQuery实现图片无限循环轮播(不借助于轮播插件)

原来我主要是用Bootstrap来实现轮播图的功能,而这次是用javaScript和jQuery来实现图片无限循环轮播! 用到的技术有:html.css.JavaScript(少).jQuery(主要) 效果展示: html代码: <body> <div id="container"><!-- left:-600px 表示:页面加载出现的第一张图片是1.jp --> <div id="list" style="le

[JS]图片自动切换效果(学习笔记)

上次在下载的网页中看到 javascript实现图片自动切换效果: <style text="text/css"> /*图片滚动栏*/.container, .container * {    margin: 0;    padding: 0;}.container {    width: 1005px;    height: 395px;    float: right;    overflow: hidden;    position: relative;    rig

JS图片Switchable切换大集合

JS图片切换大集合 利用周末2天把JS图片切换常见效果封装了下,比如:轮播,显示隐藏,淡入淡出等.废话不多说,直接看效果吧!JSFiddler链接如下: 想看JS轮播切换效果请点击我! 当然由于上传图片时候 png图片自动转换成jpg 所以左右按钮有透明,但是也没有关系,我们最主要的是看看效果是什么样的,至于图片大家可以替换.下面看看默认配置项吧!   container '',     外层容器 必填项 默认为空  contentCls  '.list',     内容所在的容器 默认为'.l

基于jQuery带标题的图片3D切换焦点图

今天给大家分享一款基于jQuery带标题的图片3D切换焦点图.这款焦点图适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗. 在线预览   源码下载 实现的代码. html代码: <div id="wowslider-container"> <div class="ws_images"> <ul> <li><a href="#"> &

js 实现图片自动切换

var pic = new Array(); var curindex=0; pic[0]="image/p1.jpg"; pic[1]="image/p2.jpg"; pic[2]="image/p3.jpg"; setInterval(go, 3000); function go(){ document.getElementById("img").src=pic[curindex]; if(curindex==pic.le

Qt自定义按钮及不同状态下图片的切换

    好久没有使用Qt了,最近在做窗体时做了一个自定义的钮铵,刚开始是想通过修改其MASK和ICON的 方式来实现.确发现效果总是不太如意,如是干脆自已定义了一个XPushButton.也将其实现方式记录发 布出来.以方便日后自已使用和给有相应问题的朋友一个小小的提示.     为了实现任意形状的窗体和保留QPushButton的特性,继承QPushButton创建一个子类. class QtXPushButton : public QPushButton {     Q_OBJECT pub

CSS实现鼠标移动图片实现切换功能

CSS实现鼠标移动图片实现切换功能:当鼠标放在一个图片上的时候可以切换为其他图片,使用javascript可以实现,下面介绍一下如何使用CSS实现此功能.代码实例如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://www.softwhy.com/" />