iOS简单的轮播 Swift实现小笔记

2017-07-26  本文已影响0人  yxnne

Yo,Come on ~ DJ ~Drop the beat,yoyo 我们公司小,开发人又少,iOS APP要赶早。临危受命我可以,安卓工程师跑不了,佛教临时抱也有点难,赶鸭子上架所谓敏捷免不了,要 告诉我自己CV战士不能做一辈子,还是励志慢慢要变屌,及时记录,学习刻苦,这样就好!

我有freeStyle,好吧~最近《中国有嘻哈》看多了。


嘿~~有点意思

言归正传,要实现一个轮播图,开始一点想法都没有,本想找个第三方框架,调下API就好了,可是网上搜了几篇文章发现也没没有太难,自己写一个能用的似乎也行吧。

这篇文章给了很大的启发,也是我主要参考的

1.基本和思路框架和文章一样一样的:就是要呈现几张图,就把几张图的宽度总和计算出,把这个和设置给ScrollView的contentSize。
class MyBannerView :UIScrollView ,UIScrollViewDelegate{
    
    var imageCount:Int = 0                      //图片总数
    var pageIndicator:UIPageControl?    //指示器引用
    var currentPage = 0                           //当前页面索引
   
 //调用该方法,传入图片
    func prepareMyBannerView(imageStrArraysNames imageName:[String]) {
        
        imageCount = imageName.count
        //遍历image集合,构造布局
        for i in 0...(imageName.count - 1) {
            //建造 UIImageView
            let imageView = UIImageView(frame: CGRect(x:CGFloat(i) * self.bounds.width,y:0,width:self.bounds.width, height:self.bounds.height) )
            /* //以后用
            //添加点击监听 UITapGestureRecognizer
            imageView.isUserInteractionEnabled = true       //可交互开关打开
            let tapRecongnizer = UITapGestureRecognizer(
                target:self,action:#selector(clickImage(_:))
            )
            imageView.addGestureRecognizer(tapRecongnizer)
            */
            self.addSubview(imageView)
            //设置轮播图图片
            imageView.image = UIImage(named: imageName[i])
            
        }
        
        //设置ScrollView的内在容量
        self.contentSize = CGSize(width:CGFloat(imageName.count ) * self.bounds.width, height :self.bounds.height)
        
        self.bounces = false                            //设置吸附属性
        self.isPagingEnabled = true                     //设置书页效果
        self.showsHorizontalScrollIndicator = false     //不要水平默认指示器
        
        //单独创建第n+1张轮播图,和第一张图片是同一张图
        let imageView = UIImageView(frame:CGRect(x:CGFloat(imageName.count) * self.bounds.width,y:0,
                                                 width : self.bounds.width,height : self.bounds.height))
     /*
        imageView.isUserInteractionEnabled = true       //可交互开关打开
        let tapRecongnizer = UITapGestureRecognizer(
            target:self,action:#selector(clickImage(_:))
        )
        imageView.addGestureRecognizer(tapRecongnizer)
      */
        imageView.image = UIImage(named:imageName[0])
        
        self.addSubview(imageView)
    }
    
2.实现UIScrollViewDelegate协议,在重写方法中计算当前页索引和指示器索引
 //手动翻页调用
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        let cPage = self.contentOffset.x / self.bounds.width
        if let indicator = pageIndicator{
            indicator.currentPage = Int(cPage)
            currentPage = Int(cPage)
        }
        currentPage %= imageCount
    }
    
    //自动播放时,调用该方法
    func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
        currentPage += 1
        if let indicator = pageIndicator{
            indicator.currentPage = currentPage % imageCount
            
        }
        
        currentPage %= imageCount
    }

    /**
     和外部的Indicator绑定
     */
    func bindPageIndicator(indicatorPageController indicator :UIPageControl  ) {
        
        pageIndicator = indicator
        pageIndicator?.backgroundColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.25)
        pageIndicator?.numberOfPages = imageCount  
        //设置代理
        self.delegate = self
        
    }

3.让他loop起来,定时器
    /**
     创建轮播图定时器
     */
    func bannerLoop() {
        let  timer =  Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(self.timerManager), userInfo: nil, repeats: true)
        
        //这句话实现多线程,如果你的ScrollView是作为TableView的headerView的话,在拖动tableView的时候让轮播图仍然能轮播就需要用到这句话
        RunLoop.current.add(timer, forMode: RunLoopMode.commonModes)
        
    }
    //定时器回调
    func timerManager() {
        //设置偏移量
        self.setContentOffset(CGPoint(x:self.contentOffset.x + self.bounds.width, y:0), animated: true)
        //当偏移量达到最后一张的时候,让偏移量置零
        if self.contentOffset.x == CGFloat(self.bounds.width) * CGFloat(imageCount) {
            self.contentOffset = CGPoint(x:0,y: 0)
        }
    }

4.每一张图片设置点击事件
//在prepareMyBannerView(imageStrArraysNames:)中
//for循环里面
            //添加点击监听 UITapGestureRecognizer
            imageView.isUserInteractionEnabled = true       //可交互开关打开
            let tapRecongnizer = UITapGestureRecognizer(
                target:self,action:#selector(clickImage(_:))
            )
            imageView.addGestureRecognizer(tapRecongnizer)

写一个协议

/**
 这个东西是图片点击的接口协议
 */
public protocol MyBannerImageClickedDelegate : NSObjectProtocol {
    
    func imageClicked(clickItem item :Int) -> Void
}

持有协议引用

    var myViewClickDelegate :MyBannerImageClickedDelegate?  //图片点击代理回调

在图片点击事件方法里面调用协议的方法

    //图片的点击监听会调用
    func clickImage(_ sender :UITapGestureRecognizer){
        
        //print(#function)
        if let clickDelegate = self.myViewClickDelegate{
            clickDelegate.imageClicked(clickItem: currentPage)
            
        }
    }
    
5.最后加个小方法:复位
  //各种位置归零
    func resetBannerPosition(){
        //当前页面索引
        currentPage  = 0
        //指示器
        pageIndicator?.currentPage = 0
        //重置偏移量
        self.contentOffset = CGPoint(x:0,y: 0)
    
    }

最后呢,使用这个MyBannerView
/**
 使用方法:banner-----------

//如若需要图片点击事件监听,让UIViewController实现MyBannerImageClickedDelegate和它的方法
比如:
    //响应轮播banner的item的回调方法
    func imageClicked(clickItem item :Int){
        print("click is \(item)")
        self.performSegue(withIdentifier: "showNews", sender: self)
        
    }
//在viewdidload()里面-------------------------

 //整一个父UIView作为容器
 let cardView = UIView(frame : CGRect(x: 0, y: 0, width: view.bounds.width, height: 200))
 //构造Banner 指定大小
 let banner = MyBannerView(frame : CGRect(x: 0, y: 0, width: view.bounds.width, height: 200))
 //设置轮播图片
 banner.prepareMyBannerView(imageStrArraysNames: ["img_banner_1","img_banner_2","img_banner_3"])
 //构造指示器,指定指示器大小
 let indicator = UIPageControl(frame: CGRect(x: view.bounds.width/2 - 50, y: 160, width: 100, height: 30))
 //绑定指示器
 banner.bindPageIndicator(indicatorPageController: indicator)
 //轮播图循环起来
 banner.bannerLoop()
 //设置一个点击事件的监听吧
 banner.myViewClickDelegate = self
 //把指示器和banner添加到父布局里面
 cardView.addSubview(banner)
 cardView.addSubview(indicator)
 view.addSubview(cardView)

//在viewWillAppear()中-------------------------
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)
        //页面出现之前,重置banner位置
        banner?.resetBannerPosition()
    }

 */

这真是一个简单的实现!这篇文章的思路看上去更好:

http://www.jianshu.com/p/19a0019f8b5f

上一篇下一篇

猜你喜欢

热点阅读