Swift - UIScrollView 循环滚动(2)
2018-10-29 本文已影响7人
S大偉
大家好,这篇文章和UIScrollView 循环滚动 1功能是相通的,但是实现的理念是完全不同的,更适合网络懒加载图片。
【实现原理】
1、当imageCount == 1时
- 在scrollView中建立一个UIImageView,不显示pageController,同时不支持滚动
2、当imageCount > 1时
- 在scrollView中建立imageCount + 1 个 UIImageView,显示pageController,pageController 的 page = imageCount
- 最后一个UIImageView赋值为第一个的值
- 当滚动到最后一张时,将scrollView的contentOff调到第一张图的位置(0, 0)
【代码】
实现语言swift
import UIKit
class JDFilmstripView: JDView {
var imageArr: Array<UIImage> = [] {
didSet {//赋值刷线UI控件 值为UIImage对象
self.reloadView()
}
}
var imageUrlArr: Array<JDImgUrlTitleModel> = [] {
didSet {//赋值刷线UI控件 值为Url对象
self.reloadView()
}
}
//是否自动跳转
var autoShow: Bool = false
//当前页面记录
var currentPage: Int = 0
//轮播控制时间计时器
lazy var autoTimer: Timer? = {
let timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
return timer
}()
//MARK: - 控件
lazy var imageVArr: Array<UIImageView> = {
var arr: Array<UIImageView> = []
return arr
}()
lazy var scrollview: UIScrollView = {
let v = UIScrollView()
v.showsVerticalScrollIndicator = false
v.showsHorizontalScrollIndicator = false
v.isPagingEnabled = true
v.bounces = false
v.delegate = self
return v
}()
lazy var pageControl: UIPageControl = {
let pc = UIPageControl()
pc.isUserInteractionEnabled = false
pc.pageIndicatorTintColor = UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 0.3)
pc.currentPageIndicatorTintColor = color_nav_red
return pc
}()
override init() {
super.init()
self.addSubview(self.scrollview)
self.addSubview(self.pageControl)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
self.scrollview.snp.makeConstraints { (make) in
make.top.right.bottom.left.equalToSuperview()
}
self.pageControl.snp.makeConstraints { (make) in
make.bottom.left.right.equalToSuperview()
make.height.equalTo(20.0)
}
}
deinit {
self.autoTimer?.invalidate()
self.autoTimer = nil
}
/*
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
// Drawing code
}
*/
}
extension JDFilmstripView {
func reloadView() {
for imagev in self.imageVArr {
imagev.removeFromSuperview()
}
self.imageVArr.removeAll()
var count: Int = 0
if self.imageUrlArr.count > 0 {
count = self.imageUrlArr.count
}
else if self.imageArr.count > 0 {
count = self.imageArr.count
}
let w = screen_width
let h = 160
self.scrollview.contentSize = CGSize(width: w * CGFloat(count), height: CGFloat(h))
var term = count
if term > 0 {
term = count + 1
}
for i in 0..<term {
let imageV = UIImageView.init()
imageV.backgroundColor = UIColor.red
imageV.frame = CGRect(x: CGFloat(i) * w, y: 0, width: w, height: CGFloat(h))
if self.imageUrlArr.count > 0 {
if i == term - 1 {
imageV.sd_setImage(with: URL(string:self.imageUrlArr[0].img) , placeholderImage: UIImage(named: "banner"))
}
else {
imageV.sd_setImage(with: URL(string:self.imageUrlArr[i].img) , placeholderImage: UIImage(named: "banner"))
}
}
else if self.imageArr.count > 0 {
if i == term - 1 {
imageV.image = self.imageArr[0]
}
else {
imageV.image = self.imageArr[i]
}
}
self.imageVArr.append(imageV)
self.scrollview.addSubview(imageV)
}
self.currentPage = 0
self.pageControl.numberOfPages = count
self.pageControl.currentPage = 0
if count > 1 {
self.pageControl.isHidden = false
self.scrollview.isScrollEnabled = true
}
else {
self.pageControl.isHidden = true
self.scrollview.isScrollEnabled = false
}
if self.autoShow && count > 1{
self.startTimer()
} else {
self.stopTimer()
}
}
@objc func startTimer() {
if self.autoShow {
self.autoTimer?.fireDate = Date.distantPast
}
}
func stopTimer() {
if self.autoShow {
self.autoTimer?.fireDate = Date.distantFuture
}
}
func endScrollMethod(_ ratio: CGFloat) {
if ratio <= 0.7 {
if self.currentPage - 1 < 0 {
self.currentPage = self.imageArr.count - 1
} else {
self.currentPage -= 1
}
}
if ratio >= 1.3 {
if self.currentPage == self.imageArr.count - 1 {
self.currentPage = 0
}
else {
self.currentPage += 1
}
}
self.startTimer()
}
@objc func timerAction() {
var count: Int = 0
if self.imageUrlArr.count > 0 {
count = self.imageUrlArr.count
}
else if self.imageArr.count > 0 {
count = self.imageArr.count
}
let w = screen_width
self.currentPage = self.currentPage + 1
if self.currentPage == count {
UIView.animate(withDuration: 0.5, animations: {
self.scrollview.contentOffset = CGPoint(x: w * CGFloat(self.currentPage), y: 0)
}) { (ok) in
if ok {
self.scrollview.contentOffset = CGPoint(x: 0, y: 0)
}
}
self.currentPage = 0
}
else {
UIView.animate(withDuration: 0.5) {
self.scrollview.contentOffset = CGPoint(x: w * CGFloat(self.currentPage), y: 0)
}
}
self.pageControl.currentPage = self.currentPage
}
}
extension JDFilmstripView: UIScrollViewDelegate {
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
self.autoTimer?.invalidate()
self.autoTimer = nil
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
let ratio = scrollView.contentOffset.x/screen_width
self.currentPage = Int(ratio)
self.pageControl.currentPage = self.currentPage
self.autoTimer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
// DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
// self.startTimer()
// }
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let ratio = scrollView.contentOffset.x/screen_width
self.currentPage = Int(ratio)
self.pageControl.currentPage = self.currentPage
}
}
【JDView】
import UIKit
import SnapKit
class JDView: UIView {
init() {
super.init(frame:CGRect(x: 0, y: 0, width: 0, height: 0))
self.backgroundColor = UIColor.white
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
/*
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
// Drawing code
}
*/
}