可自定義分頁寬度的UIScrollView(Swift實現)

最近在開發新版的APP時需要一個可自定義分頁寬度的圖片輪播組件。剛開始自己覺得在這個萬能的互聯網上早就應該有一個大俠為我們封裝好了,我只需要下載、拷貝、粘貼、修改一下代碼就可以了。誰知一圈下來,不知道是自己沒搜到,還是什么其它原因,根本就找不到。所以,一狠心就自己開干了。

我們先看一下需要的效果,如下圖:

ScrollViewPagingDemo.gif

總起來說,所需要功能有如下幾項:

  1. 可自定義分頁的寬度,并且在兩邊可以顯示相鄰兩項的一部分,從而用戶知道可以滑動;
  2. 可以無限輪播;
  3. 可以自動輪播。

對于無限輪播和自動輪播在網上一搜索一大把。這里我就不詳細講了,其原理就是第一頁和最后一頁對contentOffset做一下特殊處理,其它沒有什么玄機。

而對于定義分頁的寬度經過一番搜索之后實現的方法也基本上處于同一,原理如下圖:

image

把所能滾動的視圖的寬度定為所需要的寬度,并把它放入另外一個View中,同時把clipsToBounds設置為false,這樣相鄰的兩個頁面就會顯示在ScrollView兩邊的空白地方,而不是被切除不顯示。另外,如果能夠讓Scroll View的兩邊的空白地方也可以滑動,那么需要將View Enhancer的點擊事件同時作用到Scroll View上。

Ok,既然原理都懂了,那么下手開干就不是問題了。代碼我就不在這里貼了,可以去我的github上下載,如果喜歡別忘了star一下哦。

看一下示例是如何使用的:

class ScrollViewPagingDemoViewController: UIViewController

  override func viewDidLoad() {
    super.viewDidLoad()
    
    self.view.addSubview(scrollPagingView)
    
    // 添加你的Page view,如:
    let view1 = UIView(frame: CGRectZero)
    view1.backgroundColor = UIColor(red: 0xff/255.0, green: 0x2d/255.0, blue: 0x41/255.0, alpha: 1.0)
    view1.layer.borderColor = UIColor(red: 0xff/255.0, green: 0x2d/255.0, blue: 0x41/255.0, alpha: 1.0).CGColor
    view1.layer.borderWidth = 0.5
    view1.layer.cornerRadius = 5
    scrollPagingView.addPage(view1)

    let view2 = UIView(frame: CGRectZero)
    view2.backgroundColor = UIColor(red: 0x00/255.0, green: 0x7a/255.0, blue: 0xff/255.0, alpha: 1.0)
    view2.layer.borderColor = UIColor(red: 0x00/255.0, green: 0x7a/255.0, blue: 0xff/255.0, alpha: 1.0).CGColor
    view2.layer.borderWidth = 0.5
    view2.layer.cornerRadius = 5
    scrollPagingView.addPage(view2)
    
    let view3 = UIView(frame: CGRectZero)
    view3.backgroundColor = UIColor(red: 0x4b/255.0, green: 0xd9/255.0, blue: 0x64/255.0, alpha: 1.0)
    view3.layer.borderColor = UIColor(red: 0x4b/255.0, green: 0xd9/255.0, blue: 0x64/255.0, alpha: 1.0).CGColor
    view3.layer.borderWidth = 0.5
    view3.layer.cornerRadius = 5
    scrollPagingView.addPage(view3)
    
    let view4 = UIView(frame: CGRectZero)
    view4.backgroundColor = UIColor(red: 0xff/255.0, green: 0x96/255.0, blue: 0x00/255.0, alpha: 1.0)
    view4.layer.borderColor = UIColor(red: 0xff/255.0, green: 0x96/255.0, blue: 0x00/255.0, alpha: 1.0).CGColor
    view4.layer.borderWidth = 0.5
    view4.layer.cornerRadius = 5
    scrollPagingView.addPage(view4)

    // 用戶點擊事件,如果需要的話        
    let tapGesture = UITapGestureRecognizer(target:self, action: #selector(ScrollViewPagingDemoViewController.scrollViewTapAction(_:)))
    scrollPagingView.addGestureRecognizer(tapGesture)
  }
  
  override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    
    // 設置大小,并初始化setup方法必須調用
    self.scrollPagingView.frame = CGRect(x: 0, y: 100, width: self.view.bounds.width, height: 240)
    self.scrollPagingView.setup()    
  }
  
  private lazy var scrollPagingView: CDScrollPagingView = {
    let scrollPagingView = CDScrollPagingView()
    // 控制頁與頁之間的間隔,默認為10
    scrollPagingView.itemSpacing = 10.0
    // 是否顯示分頁指示器,默認顯示
    scrollPagingView.showPageControl = true
    // 自動切換的時間間隔,默認為3s,0表示不自動切換
    scrollPagingView.timeInterval = 3.0
    return scrollPagingView
  }()
  
  func scrollViewTapAction(sender: CDScrollPagingView){
    if let curPage = scrollPagingView.currentPage() {
      let alertController = UIAlertController(title: "系統提示",
                                              message: "您點擊第\\(curPage)頁", preferredStyle: .Alert)
      let okAction = UIAlertAction(title: "Ok", style: .Default, handler: nil)
      alertController.addAction(okAction)
      self.presentViewController(alertController, animated: true, completion: nil)
      
    }
  }
}

需要說明的有以下幾點:

  • 分頁的寬度可以通過設置CDScrollPagingView.pageWidth的值大小來控制,默認為0.85即整個寬度的85%
  • 頁與頁之間的間隔可以通過CDScrollPagingView.itemSpacing來設置,默認值為10.0
  • 分頁指示器可以控制是否顯示,控制的參數為CDScrollPagingView.showPageControl
  • 自動輪播的時間間隔可以通過scrollPagingView.timeInterval來控制,默認為3s,如果設置為0表示不進行自動輪播

另外,如果想為每個頁添加點擊事件或者頁面中控件需要添加事件處理是非常麻煩的,因為UIScrollView已經對事件做了處理,所以如果直接綁定事件處理的話會沒有任何反應,這個也把我折騰了好久。不過,對于這種輪播控件的需求大部分應該是點擊了某個頁面后進行一些處理,因此CDScrollPagingView提供了一個方法currentPage()來獲取當前是第幾頁,這樣就可以根據這個值進行處理了。具體可以看上面的示例代碼。

這個控件我也只是開發了最基礎的一些功能,不過已經滿足了自己APP的需要。后續如果需要可能還會需要增加一些動效。

如果感興趣,大家可以到github下載。

另外,也歡迎大家關注我的個人公眾號:CD826Workshop.

P.S. 這個分頁控件里面最少要有3個頁面,否則會崩潰。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,967評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,273評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,870評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,742評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,527評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,010評論 1 322
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,108評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,250評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,769評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,656評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,853評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,371評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,103評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,472評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,717評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,487評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,815評論 2 372

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,610評論 25 708
  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,151評論 4 61
  • My code: My test result: 這道題目和之前 Array里面的 permutation等等很像...
    Richardo92閱讀 512評論 0 1
  • 寂寞全因為你。不知道寂寞可以這樣:假裝美麗。 十八年了,困了青春,老了歲月,你蹣跚學步時不伴身邊,十八歲生日那天你...
    文竹君Fan閱讀 152評論 0 1
  • 在十八歲之前,從未到過南方。 確切地說,沒到過溫帶緯度再往下的地域。 那年高考報志愿和父母賭氣,年輕氣盛。一怒之下...
    小夭不是小妖閱讀 396評論 0 1