首页 > 其他分享 >iOS开发----轮播图实现

iOS开发----轮播图实现

时间:2024-09-13 23:27:02浏览次数:12  
标签:轮播 make iOS ---- func 图片 self pageControl

在iOS开发中,实现图片轮播的方法有很多,在这里介绍三种方法。

轮播图片资源准备——SDWebImage

这里我们通过第三方库SDWebImage来加载网络图片

首先通过CocoaPods下载:

接着,从网站上找想要轮播图片的地址,复制下来,y一般是下图这样,

在代码中,使用UIImageView的扩展方法sd_setImage(with:)来加载图片,并指定图片的URL。,如图:

注意:如果是这样操作的话,点击运行,会报紫色感叹号,这是运行时出错了,错误原因如下:

报错的原因在于我们复制的图片地址是HTTP,这是一个不安全的连接来访问服务,但是iOS 9及以上版本的操作系统默认启用了传输层安全(TLS),并且要求所有的HTTP连接必须通过TLS进行加密。这是为了提高数据传输的安全性。所以我们有两种解决办法:

1.将图片地址url的"http"改为"https"

2.打开Info.plist文件(Info.plist是苹果操作系统(iOS, macOS, watchOS, tvOS) 应用程序中的配置文件,用于存储应用程序的各种信息和配置设置),添加配置信息,如图

注意把Allow Arbitrary Loads 的值由No改为YES,这样前期的图片准备工作就完成了。

一.分页控制器——UIPageViewController

UIPageViewController是个高度可配置的类,你可以进行如下配置:

  • 分页的方向——水平或垂直
  • 翻页的样式——书卷翻页或者滑动翻页
  • 书脊位置——只有书卷翻页样式有效
  • 页面间距——只有滑动翻页样式有效,用来定义页面间距(inter-page spacing)

UIPageViewController类似一个视图容器,其中每个具体的视图由各自的ViewController进行维护管理,UIPageViewController只进行协调与动画布置。因此也叫分页控制器,下图可以很好的展现出UIPageViewControlelr的使用结构:

为了演示,我们通过使用改控件来实现一个图片轮播的小demo

1.定义UIPageViewController和PageControl

   lazy var pageViewController:UIPageViewController = {
        let pageVC = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
        pageVC.delegate = self
        pageVC.dataSource = self
        pageVC.setViewControllers([viewControllers[0]], direction: .forward, animated: true)
        return pageVC
    }()
    lazy var pageControl: UIPageControl = {
        let pc = UIPageControl()
        pc.backgroundColor = .clear
        pc.currentPage = 0
        pc.isEnabled = false
        pc.numberOfPages = viewControllers.count
        pc.pageIndicatorTintColor = .yellow
        pc.currentPageIndicatorTintColor = .black
        return pc
    }()

2.设置分页子视图

import UIKit
import SnapKit

class ImageViewController: UIViewController {
    
    lazy var ImageView:UIImageView = {
        let imageView = UIImageView()
        imageView.contentMode = .scaleAspectFit
        return imageView
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .white
        self.view.addSubview(ImageView)
        ImageView.snp.makeConstraints { make in
            make.left.equalTo(50)
            make.right.equalTo(-50)
            make.centerY.equalToSuperview()
            make.height.equalTo(300)
        }
    }
    

}
  var viewControllers = [ImageViewController]()
    override func viewDidLoad() {
        super.viewDidLoad()
        for i in 0..<urls.count {
            let view1 = ImageViewController()
            let url = URL(string: urls[i])
            view1.ImageView.sd_setImage(with: url)
            viewControllers.append(view1)
        }
        setUpUI()
    }

3.setUpUI()实现

  func setUpUI() {
//        添加子视图控制器到父视图上
        addChild(pageViewController)
        view.addSubview(pageViewController.view)
        //在转换子视图控制器后 立即实现子视图控制器上的方法
        pageViewController.didMove(toParent: self)
        print(pageControl.numberOfPages)
        self.view.addSubview(pageControl)
        pageControl.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.width.equalTo(width - 140)
            make.centerY.equalToSuperview().offset(150)
            make.height.equalTo(30)
        }
    }

4.代理方法实现


extension ViewController:UIPageViewControllerDelegate,UIPageViewControllerDataSource {
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        pageControl.currentPage = (pageControl.currentPage == 0) ? urls.count : pageControl.currentPage - 1
        return viewControllers[pageControl.currentPage]
    }
    
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        pageControl.currentPage = (pageControl.currentPage == urls.count - 1) ? 0 : pageControl.currentPage + 1
        return viewControllers[pageControl.currentPage]
    }
    
    
    
}

效果如下:

https://live.csdn.net/v/424264

通过这种方式创建轮播图,有一些明显的弊端,因为UIPageViewController本身是分页控制器,它控制的是子控制器的变换方式,因此创建时需要多创建几个控制器,操作的不是图片而是图片所在的控制器。

二.使用第三方库——FSPagerView

FSPageView是基于UICollectionView来实现的屏幕滑动库,特别适用于制作轮播图、产品展示、欢迎指南页面和视图控制器滑块。

主要特性如下:

  • 无限滚动
  • 自动滑动
  • 水平与垂直分页
  • 完全可自定义项目,附带预设的横幅样式项目
  • 全面可定制的 分页控制
  • 丰富的内置3D转换效果

接下来让我们看看如何实现:

1.导入项目

pod 'FSPagerView'

2.创建轮播视图

    func createFSpagerView() {
        //设置代理
        FSView.delegate = self
        FSView.dataSource = self
        //设置Item的宽高
        FSView.itemSize = CGSize(width: width - 40,height: height/4.4)
        //设置轮播以及滑动方向
        FSView.scrollDirection = .horizontal
        //设置是否无限循环
        FSView.isInfinite = true
        //设置自动滑动间隔时间
        FSView.automaticSlidingInterval = 1.2
        self.view.addSubview(FSView)
        FSView.snp.makeConstraints { make in
            make.left.equalToSuperview().offset(20)
            make.right.equalToSuperview().offset(-20)
            make.centerY.equalToSuperview()
            make.height.equalTo(height/4.3)
        }
        //设置图片滚动方式
        FSView.transformer  = FSPagerViewTransformer(type:  .linear)
        //注册
        FSView.register(FSPagerViewCell.self, forCellWithReuseIdentifier: cellID)
    }

3.创建多页控件(小圆点)FSPageControl

   func createFSControl() {

        FSControl.numberOfPages = urls.count
        FSControl.contentHorizontalAlignment = .center
        FSControl.currentPage = 0
        FSControl.hidesForSinglePage  = true
        FSControl.setStrokeColor(.green, for: .normal)
        FSControl.setStrokeColor(.green, for: .selected)
        FSControl.setFillColor(.green, for: .selected)
        self.view.addSubview(FSControl)
        FSControl.snp.makeConstraints { make in
            make.centerX.equalTo(self.FSView)
            make.width.equalTo(self.FSView.snp.width)
            make.bottom.equalTo(self.FSView.snp.bottom).offset(-5)
            make.height.equalTo(20)
        }
    }

3.代理方法实现

extension ViewController:FSPagerViewDelegate,FSPagerViewDataSource {
    func numberOfItems(in pagerView: FSPagerView) -> Int {
        //item数量
        urls.count
    }
    
    func pagerView(_ pagerView: FSPagerView, cellForItemAt index: Int) -> FSPagerViewCell {
//        创建cell
        let cell = pagerView.dequeueReusableCell(withReuseIdentifier: cellID, at: index)
        let url = URL(string:urls[index])
        cell.imageView!.sd_setImage(with: url)
        return cell
    }
    
    func pagerViewWillEndDragging(_ pagerView: FSPagerView, targetIndex: Int) {
        //当图片Page将要结束拖拽,就是图片从出现到离开后的方法
        print("\(targetIndex)图片离开屏幕")
    }
    
    func pagerView(_ pagerView: FSPagerView, willDisplay cell: FSPagerViewCell, forItemAt index: Int) {
        //当图片或者Item出现滚动后调用方法,通过该方法,可以使pagecontrol实时随图片滚动而更新
        self.FSControl.currentPage = index
    }
    

4.运行结果

轮播图2-CSDN直播

三.使用第三方库——ZCycleView

  • ZCycleView是一个使用UICollectionView实现常见图片无限轮播的开源项目‌。它支持自定义cell、自定义pageControl以及多种轮播样式‌。主要用于图片轮播场景,如新闻、广告等内容的展示‌。具有以下特点:
  • 提供了基本的轮播功能,如无限滚动和自定义轮播样式‌。
  • 可以与其他UI组件库结合使用,如SDWebImage用于图片加载,SnapKit用于自动布局‌。

让我们通过以下这个小demo来体验一下:

1.导入项目

通过CocoaPods下载:

pod 'ZCycleView'

2.创建一个ZcycleView

补充这里的占位图片的意思是当我轮播图的实际图片没有加载时,就用这张图片作为代替。

3.实现代理方法

这里的前两个方法是必须实现的,最后一个方法的作用是更换轮播图的pageControll(就是指示点)的设置信息

extension ViewController: ZCycleViewProtocol {

    
    public func cycleViewRegisterCellClasses() -> [String : AnyClass] {
        return ["ZCycleViewCellID":FSPageViewCell.self]
    }
    
    public func cycleViewConfigureCell(collectionView: UICollectionView, cellForItemAt indexPath: IndexPath, realIndex: Int) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ZCycleViewCellID", for: indexPath) as! FSPageViewCell
        
        let url = URL(string:urls[realIndex])
        
        cell.imageView.sd_setImage(with: url)
        
//        cell.imageView.image = images[realIndex]
        return cell
    }
    
    func cycleViewConfigurePageControl(_ cycleView: ZCycleView, pageControl: ZPageControl) {
        pageControl.isHidden = false
        pageControl.currentPageIndicatorTintColor = .green
        pageControl.pageIndicatorTintColor = .yellow
        pageControl.dotSize = .init(width: 10, height: 10)
        pageControl.frame = CGRect(x: 0, y: cycleView.bounds.height-25, width: cycleView.bounds.width, height: 25)
    }
}

这里注意第二个实现方法我们使用的数组索引是realIndex,不是indexPath.row,不然会数组越界。这是为什么呢?

如果我们可以查看一下第三方库相关源码:

从源码中可以发现,我们的代理方法中的第三个参数RealIndex实际做了处理,会等于indexPath.item对我们实际Item取模后的值,那么indexpath.item是多少呢?因为我们的section只有1个,所以我们这个值相当于是indexPath.row,与上面第一个方法返回的itemsCount有关,那我们看看itemsCount的值是然后赋值的吧!

这里可以发现,itemsCount做了通过三目运算符的方式做了条件赋值,前置逻辑条件(realItemsCount<=1 和 !isInfinite)是false,因此其值会等于realItemsCount *200,所以使用indexPath.row会发生数组越界。

3.自定义Cell

在代理方法的第二个实现方法里我们所使用的cell是自定义的,这里的cell是UICOllectionViewCell

这样我们就实现了轮播图的效果:

轮播图3-CSDN直播

三.FSPagerView和ZCycleView的区别

  • 设计理念‌:FSPagerView更侧重于屏幕滑动和视图控制器的滑块,而ZCycleView则专注于图片轮播。
  • 功能特性‌:FSPagerView提供了更丰富的页面间过渡动画和自定义选项,而ZCycleView则更侧重于图片轮播的自定义和与其他UI组件的结合使用。
  • 应用场景‌:FSPagerView适用于多种场景,如Banner视图、产品展示、欢迎/引导页面等,而ZCycleView则更适用于需要图片轮播的场景。

标签:轮播,make,iOS,----,func,图片,self,pageControl
From: https://blog.csdn.net/qq_74177011/article/details/142178978

相关文章

  • autogen示例九:llamaindex的智能pandasai
            相信对于许多从事Python数据分析工作的小伙伴来说,大家都对尝试使用PandasAI所带来的智能化便捷性充满兴趣。然而,由于缺乏OpenAI的API密钥,许多人只能望洋兴叹,无法真正体验到这一技术带来的便利。        现在有一种替代方案,可以让我们绕过这个限制,那......
  • 66. 加一
    题目链接66.加一思路简单模拟题题解链接官方题解关键点无时间复杂度\(O(1)\)空间复杂度\(O(1)\)代码实现:classSolution:defplusOne(self,digits:List[int])->List[int]:carry=1n=len(digits)foriin......
  • AV1 Bitstream & Decoding Process Specification--[4]:语法结构
    原文地址:https://aomediacodec.github.io/av1-spec/av1-spec.pdf没有梯子的下载地址:AV1Bitstream&DecodingProcessSpecification摘要:这份文档定义了开放媒体联盟(AllianceforOpenMedia)AV1视频编解码器的比特流格式和解码过程。规范:此文档规定了开放媒体联盟(Alliance......
  • 前端性能优化:如何有效提升网页加载速度 面试必备
    为什么要进行性能优化呢进行性能优化的原因是因为:性能的体现对干产品的影响是非常大,那么为了保证用户的留存率和转化率,我们就需要提升应用的响应速度交互体验。以保证竞争力。性能优化如何衡量性能优化如何衡量,也就是性能优化的标准是什么?游览器中控制台呢有两个重要......
  • 从0开始计算机体系结构的学习(一):FGPA预备知识与Vivado环境搭建
    引入与预备知识什么是FPGA?FPGA(Field-ProgrammableGateArray,现场可编程门阵列)是一种集成电路(IC),其硬件功能可以通过用户在现场编程来定义。与传统的ASIC(专用集成电路)不同,FPGA在制造完成后仍然可以根据需求进行重新配置。因此,它们被广泛应用于需要灵活性和可定制性且性能要求较高......
  • error:Framework ‘Pods_xxx‘ not found解决方法
    报错“FrameworkPod_xxx.framework找不到”通常意味着你的项目正在尝试链接或使用一个名为Pod_xxx.framework的框架,但是这个框架并没有被正确地添加到项目中。解决办法:1.点击项目蓝色图标,在左侧Target部分,点击你当前的项目2.在General部分往下滑,找到Frameworks,Libraries,a......
  • 大数据技术常见的几种应用架构
    1、离线计算T+1离线分析的一种经典架构:1、利用Flume从应用中收集用户行为日志;2、将用户行为日志存储在HDFS当中;3、利用Hive将SQL翻译为MapReduce可以处理的作业;4、在作业中再批处理的结果写入到数据库当中存储;5、再从数据库当中查询出我们的报表数据。  2、实时计算T+......
  • MYSQL数据库进阶篇——SQL优化
    1.插入数据优化①批量插入数据②手动提交事务③主键顺序插入大批量插入数据:2.主键优化数据组织方式页分裂:页可以为空,也可以填充一半,也可以填满,每个页包含2-N行数据,如果一行数据过大,就会行溢出。例如:页合并当删除一行数据时,实际记录并没有被物理删除,只是记录......
  • 论文复现--基于LeNet网络结构的数字识别
    前言一直就听说学习深度学习无非就是看论文,然后复现,不断循环,这段时间也看了好几篇论文(虽然都是简单的),但是对于我一个人自学,复现成功,我感觉还是挺开心的本人初学看论文的思路:聚焦网络结构与其实验的效果LeNet虽然简单,很老了,但是毕竟经典,对于初学的的我来说,我感觉还是很......
  • 11个接口性能优化方案
    11个接口性能优化方案对于从事后端开发的同学来说,肯定再熟悉不过了,因为它是一个跟开发语言无关的公共问题。该问题说简单也简单,说复杂也复杂。有时候,只需加个索引就能解决问题。有时候,需要做代码重构。有时候,需要增加缓存。有时候,需要引入一些中间件,比如mq。有时候,需要需要......