您的位置:首页 > 移动开发 > Swift

Swift实现UIScrollerView轮播

2020-03-01 11:01 357 查看
      iOS小白的第一篇博客,最近做一个项目,需要用Swift实现UIScrollView的轮播功能,不允许使用第三方的库,搜了很多代码都没找到合适的,最后几经波折,在公司小姐姐的帮助下,终于逐步完善了代码,话不多说,直接上代码,代码以4张图片轮播为例
class ViewController: UIViewController {

/// 用来承载轮播图的滚动View
var picBgScrollerView: UIScrollView!

/// 轮播图片的标签
let desArray: [String] = ["图片4", "图片1", "图片2", "图片3", "图片4", "图片1"]

/// 轮播图背景色
let colorArray: [UIColor] = [UIColor.red, UIColor.yellow, UIColor.green, UIColor.blue, UIColor.red, UIColor.yellow]

/// 真正想展示的图片个数
let imageCount: CGFloat = 4

/// 滑动前的偏移量
var preOffsetX: CGFloat = 0

/// 2.0s自动轮播
var timer: Timer?

override func viewDidLoad() {
super.viewDidLoad()

picBgScrollerView = UIScrollView(frame: CGRect(x: 0.0, y: 0.0, width: self.view.frame.width, height: self.view.frame.height))
picBgScrollerView.isPagingEnabled = true
picBgScrollerView.backgroundColor = UIColor.white
picBgScrollerView.showsHorizontalScrollIndicator = false
picBgScrollerView.contentSize = CGSize(width: self.view.frame.width * (imageCount + 2), height: self.view.frame.height - 64.0)
picBgScrollerView.contentOffset = CGPoint(x: self.view.frame.width, y: 0.0)
picBgScrollerView.delegate = self
self.view.addSubview(picBgScrollerView)

for i in 0...Int(imageCount + 1) {
let imageView: UIImageView = UIImageView(frame: CGRect(x: CGFloat(i) * self.view.frame.width, y: 0.0, width: self.view.frame.width, height: self.view.frame.height))
imageView.backgroundColor = colorArray[i]
picBgScrollerView.addSubview(imageView)

let desLabel: UILabel = UILabel(frame: .zero)
desLabel.text = desArray[i]
desLabel.textColor = UIColor.black
desLabel.font = UIFont.systemFont(ofSize: 18.0)
desLabel.textAlignment = .center
desLabel.sizeToFit()
desLabel.frame = CGRect(x: (self.view.frame.width - desLabel.frame.width) / 2.0, y: imageView.frame.height*0.55 - desLabel.frame.height, width: desLabel.frame.width, height: desLabel.frame.height)
imageView.addSubview(desLabel)
}

timer = Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(ViewController.change(timer:)), userInfo: nil, repeats: true)
}

override func viewWillDisappear(_ animated: Bool) {
self.timer?.invalidate()
self.timer = nil
}

// MARK: - Private Methods
/// 定时器执行方法
///
/// - Parameter name: 定时器
@objc private func change(timer: Timer) {

// 实际偏移量
var offsetX = picBgScrollerView.contentOffset.x + self.view.frame.width

// 根据情况进行偏移
let edgeOffsetX = self.view.frame.size.width * (imageCount + 1);  // 最后一个多余页面右边缘偏移量

// 从多余页往右边滑,赶紧先设置为第一页的位置
if (offsetX > edgeOffsetX) {
// 偏移量,不带动画,欺骗视觉
picBgScrollerView.contentOffset = CGPoint(x: self.view.frame.width, y: 0.0);
// 这里提前改变下一个要滑动到的位置为第二页
offsetX = self.view.frame.size.width * 2;
}
// 带动画滑动到下一页面
picBgScrollerView.setContentOffset(CGPoint(x: offsetX, y: 0.0), animated: true)
}

}

extension ViewController: UIScrollViewDelegate {
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let leftEdgeOffsetX: CGFloat = 0;
let rightEdgeOffsetX: CGFloat = self.view.frame.width * (imageCount + 1)

if scrollView.contentOffset.x < preOffsetX {//左滑
if (scrollView.contentOffset.x == leftEdgeOffsetX) {
picBgScrollerView.contentOffset = CGPoint(x: self.view.frame.size.width * imageCount, y: 0.0)
} else {

}
} else {//右滑
// 滑动完了之后从最后多余页赶紧切换到第一页
if (scrollView.contentOffset.x == rightEdgeOffsetX) {
picBgScrollerView.contentOffset = CGPoint(x: self.view.frame.size.width, y: 0.0);
} else {

}
}

timer = Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(ViewController.change(timer:)), userInfo: nil, repeats: true)
}

func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {

preOffsetX = scrollView.contentOffset.x
timer?.invalidate()
timer = nil
}
}
      上述代码还有个小BUG,就是滑动速度过快,第四张图片向左滑动,或者第一张图片向右滑动,由于contentoffset没来得及改变,图片会划不过去,要过一会才可以滑动,希望大神能指点一下
  • 点赞
  • 收藏
  • 分享
  • 文章举报
磨人的小喵喵 发布了1 篇原创文章 · 获赞 0 · 访问量 71 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: