效果图片:
1,头部滑动按钮封装:
//
// CJWTopView.swift
//
// Created by CJW on 16/12/23.
// Copyright © 2016年 cjw. All rights reserved.
//
import UIKit
protocol CJWTopViewDelegate:class{
func CJWTopViewClicked(topView:CJWTopView,currentIndex:Int)
}
private let kOnebtnW:CGFloat = KEYSEECENSIZE.width/3
class CJWTopView: UIView {
private var titles = [String]()
weak var delegate:CJWTopViewDelegate?
private lazy var buttons:[UIButton] = [UIButton]()
private var currentIndex : Int = 0
//MARK:- 懒加载控件
private lazy var bgScrollView:UIScrollView = {
let scorllView:UIScrollView = UIScrollView()
scorllView.backgroundColor = UIColor.yellowColor()
scorllView.showsHorizontalScrollIndicator = false
//scorllView上的按钮支持滑动;
scorllView.panGestureRecognizer.delaysTouchesBegan = true
return scorllView
}()
init(frame: CGRect,title:[String]) {
self.titles = title
super.init(frame: frame)
setTopUpUI()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//MARK:- 设置UI
extension CJWTopView
{
//1
private func setTopUpUI(){
//添加背景的View
addSubview(bgScrollView)
bgScrollView.frame = bounds
//scrollView的内容大小
print("几个-\(self.titles.count)")
let contentX:CGFloat = (kOnebtnW+10) * CGFloat(self.titles.count)
bgScrollView.contentSize = CGSize(width: contentX+10, height: 0)
//2
setSubViewbtnFrame()
}
//2
private func setSubViewbtnFrame(){
let abtnY : CGFloat = 5.0
let abtnH : CGFloat = 40
var abtnX : CGFloat = 10
for (index,title) in titles.enumerate(){
print("index->\(index)")
let abtn = UIButton()
abtn.setTitle(title, forState:.Normal)
abtn.tag = index
abtn.backgroundColor = UIColor.lightGrayColor()
abtn.layer.cornerRadius = 8.0
abtnX = 10 + (kOnebtnW+10) * CGFloat(index)
abtn.frame = CGRect(x: abtnX, y: abtnY, width: kOnebtnW, height: abtnH)
bgScrollView.addSubview(abtn)
buttons.append(abtn)
//点击事件
abtn.addTarget(self, action: #selector(oneBtnClicked(_:)), forControlEvents: .TouchUpInside)
}
}
}
//MARK:- 按钮的点击事件
extension CJWTopView
{
func oneBtnClicked(button:UIButton) -> () {
print("点击的第\(button.tag)个按钮")
self.delegate?.CJWTopViewClicked(self, currentIndex: button.tag)
}
}
// MARK:- 对外暴露的方法
extension CJWTopView {
func setTitleWithProgress(progress : CGFloat, sourceIndex : Int, targetIndex : Int) {
// .取出sourceLabel/targetLabel
let sourceLabel = buttons[sourceIndex]
let targetLabel = buttons[targetIndex]
// 记录最新的index
currentIndex = targetIndex
}
}
2,下面VC的分装
//
// CJWContentVCs.swift
//
// Created by CJW on 16/12/23.
// Copyright © 2016年 cjw. All rights reserved.
//
import UIKit
protocol CJWContentVCsDelegate : class {
func pageContentView(contentView : CJWContentVCs, progress : CGFloat, sourceIndex : Int, targetIndex : Int)
}
private let collectViewID:String = "collectViewID"
class CJWContentVCs: UIView {
private var childVCs : [UIViewController]
private weak var persentVC:UIViewController?
private var isForbidScrollDelegate : Bool = false
private var startOffsetX : CGFloat = 0
weak var delegate : CJWContentVCsDelegate?
//MARK:- 懒加载控件
private lazy var collectView : UICollectionView = {[weak self] in
let layout = UICollectionViewFlowLayout()
layout.itemSize = self!.bounds.size
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0
layout.scrollDirection = .Horizontal
let conllectV:UICollectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
conllectV.pagingEnabled = true
conllectV.bounces = false
conllectV.scrollsToTop = false
conllectV.delegate = self
conllectV.dataSource = self
conllectV.showsVerticalScrollIndicator = false
conllectV.showsHorizontalScrollIndicator = false
conllectV.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: collectViewID)
return conllectV
}()
init(frame: CGRect,childVCs:[UIViewController],persentVC:UIViewController) {
self.childVCs = childVCs
self.persentVC = persentVC
super.init(frame: frame)
setContentUI()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//MARK:- 设置UI
extension CJWContentVCs
{
private func setContentUI(){
for childVc in childVCs{
persentVC?.addChildViewController(childVc)
}
addSubview(collectView)
collectView.frame = bounds
}
}
//MARK:- collectionViewDelegate
extension CJWContentVCs:UICollectionViewDataSource
{
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return childVCs.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(collectViewID, forIndexPath: indexPath)
for view in cell.contentView.subviews {
view.removeFromSuperview()
}
let child = childVCs[indexPath.item]
child.view.frame = cell.contentView.bounds
cell.contentView.addSubview(child.view)
return cell
}
}
// MARK:- 遵守UICollectionViewDelegate
extension CJWContentVCs : UICollectionViewDelegate {
func scrollViewWillBeginDragging(scrollView: UIScrollView) {
isForbidScrollDelegate = false
startOffsetX = scrollView.contentOffset.x
}
func scrollViewDidScroll(scrollView: UIScrollView) {
// 0.判断是否是点击事件
if isForbidScrollDelegate { return }
// 1.定义获取需要的数据
var progress : CGFloat = 0
var sourceIndex : Int = 0
var targetIndex : Int = 0
// 2.判断是左滑还是右滑
let currentOffsetX = scrollView.contentOffset.x
let scrollViewW = scrollView.bounds.width
if currentOffsetX > startOffsetX { // 左滑
// 1.计算progress
progress = currentOffsetX / scrollViewW - floor(currentOffsetX / scrollViewW)
// 2.计算sourceIndex
sourceIndex = Int(currentOffsetX / scrollViewW)
// 3.计算targetIndex
targetIndex = sourceIndex + 1
if targetIndex >= childVCs.count {
targetIndex = childVCs.count - 1
}
// 4.如果完全划过去
if currentOffsetX - startOffsetX == scrollViewW {
progress = 1
targetIndex = sourceIndex
}
} else { // 右滑
// 1.计算progress
progress = 1 - (currentOffsetX / scrollViewW - floor(currentOffsetX / scrollViewW))
// 2.计算targetIndex
targetIndex = Int(currentOffsetX / scrollViewW)
// 3.计算sourceIndex
sourceIndex = targetIndex + 1
if sourceIndex >= childVCs.count {
sourceIndex = childVCs.count - 1
}
}
// 3.将progress/sourceIndex/targetIndex传递给titleView
delegate?.pageContentView(self, progress: progress, sourceIndex: sourceIndex, targetIndex: targetIndex)
}
}
// MARK:- 对外暴露的方法
extension CJWContentVCs {
func setCurrentIndex(currentIndex : Int) {
// 1.记录需要进制执行代理方法
isForbidScrollDelegate = true
// 2.滚动正确的位置
let offsetX = CGFloat(currentIndex) * collectView.frame.width
collectView.setContentOffset(CGPoint(x: offsetX, y: 0), animated: false)
}
}
3,使用这两个
//
// ViewController.swift
//
// Created by CJW on 16/12/23.
// Copyright © 2016年 cjw. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
private lazy var topView:CJWTopView = {
let topFrame:CGRect = CGRect(x: 0, y: 20, width: KEYSEECENSIZE.width, height: 50)
let titles:[String] = ["第一页","第二页","第三页","第四页","第五页","写几个","就有几个"]
let topV = CJWTopView(frame: topFrame, title: titles)
topV.delegate = self
return topV
}()
private lazy var contionView:CJWContentVCs = {
let contentFrame:CGRect = CGRect(x: 0, y: 20+50, width: KEYSEECENSIZE.width, height: KEYSEECENSIZE.height-70)
var childVCs = [UIViewController]()
for _ in 0...6{
let vc = UIViewController()
vc.view.backgroundColor = UIColor(r:CGFloat(arc4random_uniform(255)),g:CGFloat(arc4random_uniform(255)),b:CGFloat(arc4random_uniform(255)))
childVCs.append(vc)
}
let contenV = CJWContentVCs(frame: contentFrame, childVCs: childVCs, persentVC: self)
return contenV
}()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.view.addSubview(topView)
self.view.addSubview(contionView)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension ViewController:CJWTopViewDelegate{
func CJWTopViewClicked(topView: CJWTopView, currentIndex: Int) {
contionView.setCurrentIndex(currentIndex)
}
}