您的位置:首页 > 理论基础 > 计算机网络

写一个可以使用kingfisher加载图片的轮播器PPTView

2016-04-25 10:49 519 查看

前言:关于图片轮播的第三方资源已经很多了,其中大多的使用都是很简单方便的, 但是从oc到swift上面来, 就写一写基本的常用的”控件”当作熟悉吧, 如果在这个过程中能帮到一些正在学习的人,个人也还是很开心的

最终效果(和其他效果相似)



一. 构思

本次主要实现无限循环滚动, 手动滚动, 显示标题, 响应点击事件, 支持加载网络和本地的图片, 同时这个轮播的一点小小的特点是 : 允许你自己使用第三方的图片加载框架(kingfisher, SDWebImage…)来加载网络图片

注意暂时不支持直接在storyboard中使用, 直接将轮播的view加载到storyboard中的view上面即可使用

1. 轮播图的实现原理, 百度一下就可以找到很多, 这里我就简单说一下

1.1 直接在ScrollView上添加和图片个数一样的imageVIew来显示图片, 在滚动的时候调整ScrollView的contentOffSet即可, 但是图片较多的时候可能占用许多的内存

1.2 在ScrollView上添加两个imageView来显示图片, 其中一个imageView(A)始终显示在屏幕上, 另一个imageView(B)根据滑动的方向添加到对应的左或者右边, 在每次滚动完成的时候,通过调整ScrollView的contentOffSet将 A 始终位于当前屏幕上显示更改后的图片, 滚动过程如下



1.3 在ScrollView上添加三个imageView来显示图片, 原理和上面1.2 有点类似, 每次在滚动完成的时候将中间的那个imageView显示在屏幕上, 滚动过程如下



这里笔者就选择了三个ImageView来实现

2. 实现图片循环滚动

2.1 若使用1.1 的方式实现循环滚动比较难

2.1 若使用1.2和1.3 的方式,原理类似, 用一个数组来缓存”图片”(可能是Url) 根据左右滑动的方向计算出将要显示下一张图片的下标, 只需要处理下标为0 和数组的最后一个元素

3. 响应点击事件 给显示在屏幕上的哪一个imageView添加手势, 通过closures(或代理)响应外部点击

4. 允许使用第三方网络库来加载图片,这里我是用到了blosure来加载每一张图片(您也可以使用代理, 类似于UItableViewDatasource,加载的cell个数, cell的内容…)

5. 注意在手动滚动图片的时候要注意关闭计时器,以免松手的时候出现快速滚动, 同时在松手后要开启计时器,继续自动滚动, 这个具体待UIScrollView的代理方法处理里面可以看到

二 实现部分



####a.从这张图片中我们可以知道这个PPTView需要的控件有



具体的处理您可以直接看源码

b. 逻辑处理

// 初始化
public init(imagesCount: Int, setupImageForImageView: SetupImageForImageView?, pageDidClick: PageDidClickAction?) {

// 这个blosure 处理点击
self.pageDidClick = pageDidClick
// 这个blosure获取图片 相当于UITableView的cellForRow...方法
self.setupImageForImageView = setupImageForImageView
// 相当于UITableView的numberOfRows...方法
self.imagesCount = imagesCount

super.init(frame: CGRectZero)
// 这里面添加了各个控件, 和设置了初始的图片和title
initialization()

}

// 设置各个控件的位置和scrollView的contentSize(imageView的三倍宽度)
override public func layoutSubviews()


UIScrollView代理方法

// 手指触摸到时
public func scrollViewWillBeginDragging(scrollView: UIScrollView) {
if autoScroll {
stopTimer()

}
}

// 松开手指时
public func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if autoScroll {
startTimer()

}
}

/// 代码设置scrollview的contentOffSet滚动完成后调用
public func scrollViewDidEndScrollingAnimation(scrollView: UIScrollView) {
// 重新加载图片
loadImages()

}

/// scrollview的滚动是由拖拽触发的时候,在它将要停止时调用
public func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
// fabs 绝对值
if fabs(scrollView.contentOffset.x - scrollView.bounds.size.width) > scrollView.bounds.size.width / 2 {

scrollDirection = scrollView.contentOffset.x > bounds.size.width ? .Left : .Right
// 重新加载图片
loadImages()
}

}


加载图片的部分, 里面涉及到了一点小的数学计算(希望读者自己理解下)

private
4000
func loadImages() {

// 根据滚动方向不同设置将要显示的图片下标
switch scrollDirection {

case .Left:
currentIndex = (currentIndex + 1) % imagesCount

case .Right:
currentIndex = (currentIndex - 1 + imagesCount) % imagesCount

}

leftIndex = (currentIndex - 1 + imagesCount) % imagesCount
rightIndex = (currentIndex + 1) % imagesCount

// 使用closure将imageVIew"传递"给外部的调用者来加载图片, 这样就达到了在使用的时候可以以任何方式来加载图片了
setupImageForImageView?(imageView: currentImageView, index: currentIndex)
setupImageForImageView?(imageView: rightImageView, index: rightIndex)
setupImageForImageView?(imageView: leftImageView, index: leftIndex)

pageControl.currentPage = currentIndex
if let titles = titlesArray { // 已经添加了textLabel 直接设置文字即可
textLabel.text = titles[currentIndex]

}

// 始终将currentImageView显示在屏幕上
scrollView.contentOffset = CGPoint(x: bounds.size.width, y: 0)

}


实现自动滚动的部分就较简单了, 使用NSTimer, 在倒计时完成的时候的响应方法里面加载图片就ok了, 具体的实现大家阅读源码吧


>详细请移步源码, 如果您觉得有帮助,不妨给个star鼓励一下,欢迎关注

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  图片 控件 swift 网络