Yo,Come on ~ DJ ~Drop the beat谱煤,yoyo 我們公司小彤悔,開發(fā)人又少嘉抓,iOS APP要趕早。臨危受命我可以晕窑,安卓工程師跑不了抑片,佛教臨時抱也有點難,趕鴨子上架所謂敏捷免不了杨赤,要 告訴我自己CV戰(zhàn)士不能做一輩子敞斋,還是勵志慢慢要變屌,及時記錄疾牲,學(xué)習(xí)刻苦植捎,這樣就好!
我有freeStyle阳柔,好吧~最近《中國有嘻哈》看多了焰枢。
言歸正傳,要實現(xiàn)一個輪播圖舌剂,開始一點想法都沒有济锄,本想找個第三方框架,調(diào)下API就好了霍转,可是網(wǎng)上搜了幾篇文章發(fā)現(xiàn)也沒沒有太難拟淮,自己寫一個能用的似乎也行吧。
1.基本和思路框架和文章一樣一樣的:就是要呈現(xiàn)幾張圖,就把幾張圖的寬度總和計算出角虫,把這個和設(shè)置給ScrollView的contentSize沾谓。
class MyBannerView :UIScrollView ,UIScrollViewDelegate{
var imageCount:Int = 0 //圖片總數(shù)
var pageIndicator:UIPageControl? //指示器引用
var currentPage = 0 //當(dāng)前頁面索引
//調(diào)用該方法,傳入圖片
func prepareMyBannerView(imageStrArraysNames imageName:[String]) {
imageCount = imageName.count
//遍歷image集合戳鹅,構(gòu)造布局
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) )
/* //以后用
//添加點擊監(jiān)聽 UITapGestureRecognizer
imageView.isUserInteractionEnabled = true //可交互開關(guān)打開
let tapRecongnizer = UITapGestureRecognizer(
target:self,action:#selector(clickImage(_:))
)
imageView.addGestureRecognizer(tapRecongnizer)
*/
self.addSubview(imageView)
//設(shè)置輪播圖圖片
imageView.image = UIImage(named: imageName[i])
}
//設(shè)置ScrollView的內(nèi)在容量
self.contentSize = CGSize(width:CGFloat(imageName.count ) * self.bounds.width, height :self.bounds.height)
self.bounces = false //設(shè)置吸附屬性
self.isPagingEnabled = true //設(shè)置書頁效果
self.showsHorizontalScrollIndicator = false //不要水平默認指示器
//單獨創(chuàng)建第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 //可交互開關(guān)打開
let tapRecongnizer = UITapGestureRecognizer(
target:self,action:#selector(clickImage(_:))
)
imageView.addGestureRecognizer(tapRecongnizer)
*/
imageView.image = UIImage(named:imageName[0])
self.addSubview(imageView)
}
2.實現(xiàn)UIScrollViewDelegate協(xié)議,在重寫方法中計算當(dāng)前頁索引和指示器索引
//手動翻頁調(diào)用
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
}
//自動播放時枫虏,調(diào)用該方法
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
//設(shè)置代理
self.delegate = self
}
3.讓他loop起來妇穴,定時器
/**
創(chuàng)建輪播圖定時器
*/
func bannerLoop() {
let timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(self.timerManager), userInfo: nil, repeats: true)
//這句話實現(xiàn)多線程爬虱,如果你的ScrollView是作為TableView的headerView的話,在拖動tableView的時候讓輪播圖仍然能輪播就需要用到這句話
RunLoop.current.add(timer, forMode: RunLoopMode.commonModes)
}
//定時器回調(diào)
func timerManager() {
//設(shè)置偏移量
self.setContentOffset(CGPoint(x:self.contentOffset.x + self.bounds.width, y:0), animated: true)
//當(dāng)偏移量達到最后一張的時候腾它,讓偏移量置零
if self.contentOffset.x == CGFloat(self.bounds.width) * CGFloat(imageCount) {
self.contentOffset = CGPoint(x:0,y: 0)
}
}
4.每一張圖片設(shè)置點擊事件
//在prepareMyBannerView(imageStrArraysNames:)中
//for循環(huán)里面
//添加點擊監(jiān)聽 UITapGestureRecognizer
imageView.isUserInteractionEnabled = true //可交互開關(guān)打開
let tapRecongnizer = UITapGestureRecognizer(
target:self,action:#selector(clickImage(_:))
)
imageView.addGestureRecognizer(tapRecongnizer)
寫一個協(xié)議
/**
這個東西是圖片點擊的接口協(xié)議
*/
public protocol MyBannerImageClickedDelegate : NSObjectProtocol {
func imageClicked(clickItem item :Int) -> Void
}
持有協(xié)議引用
var myViewClickDelegate :MyBannerImageClickedDelegate? //圖片點擊代理回調(diào)
在圖片點擊事件方法里面調(diào)用協(xié)議的方法
//圖片的點擊監(jiān)聽會調(diào)用
func clickImage(_ sender :UITapGestureRecognizer){
//print(#function)
if let clickDelegate = self.myViewClickDelegate{
clickDelegate.imageClicked(clickItem: currentPage)
}
}
5.最后加個小方法:復(fù)位
//各種位置歸零
func resetBannerPosition(){
//當(dāng)前頁面索引
currentPage = 0
//指示器
pageIndicator?.currentPage = 0
//重置偏移量
self.contentOffset = CGPoint(x:0,y: 0)
}
最后呢跑筝,使用這個MyBannerView
/**
使用方法:banner-----------
//如若需要圖片點擊事件監(jiān)聽,讓UIViewController實現(xiàn)MyBannerImageClickedDelegate和它的方法
比如:
//響應(yīng)輪播banner的item的回調(diào)方法
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))
//構(gòu)造Banner 指定大小
let banner = MyBannerView(frame : CGRect(x: 0, y: 0, width: view.bounds.width, height: 200))
//設(shè)置輪播圖片
banner.prepareMyBannerView(imageStrArraysNames: ["img_banner_1","img_banner_2","img_banner_3"])
//構(gòu)造指示器瞒滴,指定指示器大小
let indicator = UIPageControl(frame: CGRect(x: view.bounds.width/2 - 50, y: 160, width: 100, height: 30))
//綁定指示器
banner.bindPageIndicator(indicatorPageController: indicator)
//輪播圖循環(huán)起來
banner.bannerLoop()
//設(shè)置一個點擊事件的監(jiān)聽吧
banner.myViewClickDelegate = self
//把指示器和banner添加到父布局里面
cardView.addSubview(banner)
cardView.addSubview(indicator)
view.addSubview(cardView)
//在viewWillAppear()中-------------------------
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
//頁面出現(xiàn)之前曲梗,重置banner位置
banner?.resetBannerPosition()
}
*/
這真是一個簡單的實現(xiàn)!這篇文章的思路看上去更好: