Swift輪播圖

最近在學(xué)習(xí)swift油额,就用swift實(shí)現(xiàn)輪播圖來練習(xí)一下

輪播圖的創(chuàng)建有兩種方式:
    1>可以用scrollview創(chuàng)建3個view叠纷,自己實(shí)現(xiàn)循環(huán)利用
    2>利用collectionView由系統(tǒng)來處理item的循環(huán)利用問題

顯然使用collectionView實(shí)現(xiàn)的方式比較簡單。

輪播圖由兩部分組成潦嘶,collectionView和一個pageControl涩嚣。自定義一個CarouselView,懶加載創(chuàng)建collectionView和pageControl:

fileprivate lazy var carouselCollectionView : UICollectionView = { [unowned self] in
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = UICollectionViewScrollDirection.horizontal//橫向滾動
        layout.itemSize = CGSize(width: kViewWidth, height: kViewHeight)
        layout.minimumLineSpacing = 0//行間距為0
        let carouselCollectionView:UICollectionView = UICollectionView(frame: self.bounds, collectionViewLayout: layout)
        carouselCollectionView.showsHorizontalScrollIndicator = false
        carouselCollectionView.isPagingEnabled = true//按頁滾動
        carouselCollectionView.backgroundColor = UIColor.white
        carouselCollectionView.register(CarouselCollectionViewCell.self, forCellWithReuseIdentifier: CellIdentifier)//注冊自定義cell
        //添加代理
        carouselCollectionView.dataSource = self
        carouselCollectionView.delegate = self
        return carouselCollectionView
    }()
    
    fileprivate lazy var pageControl : UIPageControl = {
        let pageControl:UIPageControl = UIPageControl()
        pageControl.translatesAutoresizingMaskIntoConstraints = false//用代碼為pageControl添加NSLayoutConstraint的時候,需要設(shè)置
        pageControl.numberOfPages = 1
        return pageControl
    }()

重寫自定義視圖的初始化方法

init(Y: CGFloat,H:CGFloat) {
        kViewHeight = H
        super.init(frame: CGRect(x: 0, y: Y, width: kViewWidth, height: kViewHeight))
        setupUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

使用extension為CarouselView添加一個布局方法

//MARK:- setup UI
extension CarouselView {
    func setupUI() {
        self.addSubview(carouselCollectionView)
        self.addSubview(pageControl)
        //將pageControl添加到自定義視圖后掂僵,給pageControl添加約束
        let rightConstraint:NSLayoutConstraint = NSLayoutConstraint(item: pageControl, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1.0, constant: -10)
        let bottomConstraint:NSLayoutConstraint = NSLayoutConstraint(item: pageControl, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1.0, constant: -5)
        let heightConstraint:NSLayoutConstraint = NSLayoutConstraint(item: pageControl, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 20)
        pageControl.superview?.addConstraint(rightConstraint)
        pageControl.superview?.addConstraint(bottomConstraint)
        pageControl.superview?.addConstraint(heightConstraint)
    }
}

創(chuàng)建一個數(shù)組用來存儲自定義CarouselModel

var carouselModelArr : [CarouselModel]? {
        didSet {
            //數(shù)組發(fā)生變化時刷新collectionView
            self.carouselCollectionView.reloadData()
            pageControl.numberOfPages = carouselModelArr?.count ?? 0
            //初識時航厚,讓collectionView滾動到中間某個位置,使用戶可以向前翻頁
            let index = (carouselModelArr?.count ?? 0)*10
            self.carouselCollectionView.scrollToItem(at: IndexPath(item: index, section: 0), at: .left, animated: false)
            //添加計時器
            removeTimer()
            addTimer()
        }
    }

自定義一個CarouselModel用來接收數(shù)據(jù)

class CarouselModel: NSObject {

    var title:String = ""
    var pic_url:String = ""
    
    init(dic:[String:NSObject]) {
        super.init()
        //kvc方法锰蓬,字典轉(zhuǎn)模型
        setValuesForKeys(dic)
    }
    //獲取的數(shù)據(jù)中沒定義的鍵值在這里處理
    override func setValue(_ value: Any?, forUndefinedKey key: String) {
//        print("undefined key : \(key), value : \(value)")
    }
}

創(chuàng)建自定義cell
自定義 cell包括兩部分:
1>展示圖片用的imageView
2>展示文字title的Label

import UIKit
import SDWebImage

class CarouselCollectionViewCell: UICollectionViewCell {
    
    var imageView = UIImageView()
    
    var titleLabel = UILabel()
    
    var carouselModel : CarouselModel? {
        didSet {
            //設(shè)置屬性時給label和imageView賦值
            titleLabel.text = carouselModel?.title
            //使用SDWebImage設(shè)置imageView圖片
            imageView.sd_setImage(with: URL(string: (carouselModel?.pic_url ?? "")!), placeholderImage: UIImage(named: "placehold"))
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension CarouselCollectionViewCell {
    func setupUI() {
        imageView.frame = self.bounds
        titleLabel.frame = CGRect(x: 0, y: self.bounds.size.height - 30, width: self.bounds.size.width, height: 30)
        titleLabel.backgroundColor = UIColor(white: 0.4, alpha: 0.3)
        titleLabel.textColor = .white
        self.addSubview(imageView)
        self.addSubview(titleLabel)
    }
}

自定義CarouselView遵循 DataSource 協(xié)議

//MARK:- collectionViewDataSource
extension CarouselView : UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        //返回10000倍item實(shí)現(xiàn)無限輪播幔睬,因?yàn)閏ollectionView的重用機(jī)制,并不會創(chuàng)建這么多item芹扭,不用擔(dān)心內(nèi)存問題
        return 10000*(carouselModelArr?.count ?? 0);
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        //使用自定義item:CarouselCollectionViewCell
        let collectionItem = collectionView.dequeueReusableCell(withReuseIdentifier: CellIdentifier, for: indexPath) as! CarouselCollectionViewCell
        let index = indexPath.item % carouselModelArr!.count
        collectionItem.carouselModel = carouselModelArr![index]
        return collectionItem
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let item = collectionView.cellForItem(at: indexPath) as! CarouselCollectionViewCell
        print("title : \(item.titleLabel.text)")
    }
}

自定義CarouselView遵循Delegate協(xié)議

//MARK:- collectionViewDelegate
extension CarouselView : UICollectionViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        //當(dāng)偏移超過page的一半時pageControl調(diào)到下一個
        let offset = scrollView.contentOffset.x + kViewWidth / 2
        pageControl.currentPage = Int(offset / kViewWidth) % (carouselModelArr?.count ?? 1)
    }
    
    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        //用戶開始拖拽時麻顶,移除定時器
        removeTimer()
    }
    
    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        //用戶停止拖拽時,打開定時器
        addTimer()
    }
}

添加計時器舱卡,使collection View滾動起來

//MARK:- 添加計時器
extension CarouselView {
    func addTimer() {
        timer = Timer(timeInterval: 3.0, target: self, selector: #selector(scrollToNextPage), userInfo: nil, repeats: true)
        RunLoop.main.add(timer!, forMode: .commonModes)
    }
    
    func removeTimer() {
        timer?.invalidate()
        timer = nil
    }
    
    func scrollToNextPage() {
        let offsetX = carouselCollectionView.contentOffset.x + kViewWidth//當(dāng)前偏移量加上一頁的寬度
        carouselCollectionView.setContentOffset(CGPoint(x: offsetX, y: 0), animated: true)
        
    }
}

此時澈蚌,一個簡單的輪播圖就完成了!

下面是輪播圖的使用:

import UIKit
import AFNetworking

class ViewController: UIViewController {
    //創(chuàng)建自定義carousView
//    let carouselView = CarouselView(Y: 64, H: 200)//需要毛玻璃效果時Y為64
    let carouselView = CarouselView(Y: 0, H: 200)//不需要毛玻璃效果時Y灼狰,為0。

    var modelArr = [CarouselModel]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        getArrayFromWeb()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

extension ViewController {
    func setupUI() {
//        self.automaticallyAdjustsScrollViewInsets = false//需要毛玻璃效果時設(shè)置(是否根據(jù)所在界面的navigationbar與tabbar的高度浮禾,自動調(diào)整scrollview的inset.默認(rèn)是true)
        self.navigationController?.navigationBar.isTranslucent = false//不需要毛玻璃效果時設(shè)置
        self.view.addSubview(carouselView)
    }
    //使用AFN解析數(shù)據(jù)
    func getArrayFromWeb() {
        let manager = AFHTTPSessionManager()
        manager.get("http://www.douyutv.com/api/v1/slide/6", parameters: ["version" : "2.300"], progress: nil, success: { (task:URLSessionDataTask, json:Any) in
//            print("jsonData: \(json)")
            guard let dataDic = json as? [String : NSObject] else { return }
            guard let dataArr = dataDic["data"] as? [[String : NSObject]] else { return }
            for dic in dataArr {
                self.modelArr.append(CarouselModel(dic: dic))
            }
            //獲取完數(shù)據(jù)交胚,將數(shù)組賦給carouselView的carouselModelArr
            self.carouselView.carouselModelArr = self.modelArr
        }) { (task:URLSessionDataTask?, error:Error) in
            print("error : \(error)")
        }
    }
}

GitHub地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者盈电。
  • 序言:七十年代末蝴簇,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子匆帚,更是在濱河造成了極大的恐慌熬词,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,843評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吸重,死亡現(xiàn)場離奇詭異互拾,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)嚎幸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評論 3 392
  • 文/潘曉璐 我一進(jìn)店門颜矿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人嫉晶,你說我怎么就攤上這事骑疆√锲” “怎么了?”我有些...
    開封第一講書人閱讀 163,187評論 0 353
  • 文/不壞的土叔 我叫張陵箍铭,是天一觀的道長泊柬。 經(jīng)常有香客問我,道長诈火,這世上最難降的妖魔是什么兽赁? 我笑而不...
    開封第一講書人閱讀 58,264評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮柄瑰,結(jié)果婚禮上闸氮,老公的妹妹穿的比我還像新娘。我一直安慰自己教沾,他們只是感情好蒲跨,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,289評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著授翻,像睡著了一般或悲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上堪唐,一...
    開封第一講書人閱讀 51,231評論 1 299
  • 那天巡语,我揣著相機(jī)與錄音,去河邊找鬼淮菠。 笑死男公,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的合陵。 我是一名探鬼主播枢赔,決...
    沈念sama閱讀 40,116評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼拥知!你這毒婦竟也來了踏拜?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,945評論 0 275
  • 序言:老撾萬榮一對情侶失蹤低剔,失蹤者是張志新(化名)和其女友劉穎速梗,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體襟齿,經(jīng)...
    沈念sama閱讀 45,367評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡姻锁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,581評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了猜欺。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片屋摔。...
    茶點(diǎn)故事閱讀 39,754評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖替梨,靈堂內(nèi)的尸體忽然破棺而出钓试,到底是詐尸還是另有隱情装黑,我是刑警寧澤,帶...
    沈念sama閱讀 35,458評論 5 344
  • 正文 年R本政府宣布弓熏,位于F島的核電站恋谭,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏挽鞠。R本人自食惡果不足惜疚颊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,068評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望信认。 院中可真熱鬧材义,春花似錦、人聲如沸嫁赏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽潦蝇。三九已至款熬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間攘乒,已是汗流浹背贤牛。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留则酝,地道東北人殉簸。 一個月前我還...
    沈念sama閱讀 47,797評論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像沽讹,于是被迫代替她去往敵國和親般卑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,654評論 2 354

推薦閱讀更多精彩內(nèi)容