Swift PageViewController封装

2018-10-29  本文已影响34人  S大偉

如果自己可以写的,最好自己写,不要对第三方封装过于依赖。如果他人写的感觉可以,可以借鉴学习,然后自己尝试模仿着去写,如果真的要用,还望学习一下,免得忽然出来个坑,然而自己的一脸茫然。

苹果官方提供了UIPageViewController用于分页控制ViewController。让我们使用来封装一个顶部有选择菜单PageViewController控制器。

【顶部有选择菜单】

import UIKit
enum PageBarViewType {
    case None
    case TextColor    //切换时改变颜色
    case FontSize     //切换时改变字体大小
}
//使用协议进行回掉
protocol PageBarViewDelegate {
    func changeSelected(index:Int);
}

class JDPageBarView: UIView {
    
    //MARK: - View
    lazy var scrollView:UIScrollView = {[unowned self] in
        let sv = UIScrollView()
        sv.showsHorizontalScrollIndicator = false
        return sv
     }()
    lazy var viewLine:UIView = {[unowned self] in
        let lineV = UIView()
        return lineV
    }()

    //MARK: - Data
    var type: PageBarViewType = .None {
        willSet {
            if newValue == .FontSize {
                self.viewLine.backgroundColor = .white
                self.backgroundColor = color_nav_red
            }
            else if newValue == .TextColor {
                self.viewLine.backgroundColor = color_nav_red
            }
        }
    }
    
    var countOfPage:Int = 4
    var titles:Array<String> = [] {
        didSet {
            reloadData()
        }
    }
    var delegate:PageBarViewDelegate?
    
    //MARK - func
    override init(frame: CGRect) {
        super.init(frame: frame)
        scrollView.frame = CGRect(x: 0, y: 0, width: frame.size.width, height: self.frame.size.height)
        self.addSubview(scrollView)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        
    }
    
    /*
     // Only override draw() if you perform custom drawing.
     // An empty implementation adversely affects performance during animation.
     override func draw(_ rect: CGRect) {
     // Drawing code
     }
     */
    
}

extension JDPageBarView {
    func reloadData() {
        
        if titles.count < countOfPage {
            countOfPage = titles.count
        }
        
        let w:CGFloat = frame.size.width / CGFloat.init(countOfPage)
        scrollView.contentSize = CGSize.init(width: w * CGFloat.init(titles.count), height: frame.size.height)
        viewLine.frame = CGRect(x: 0, y: frame.size.height - 2, width: w, height: 2)
        for i in 0..<self.titles.count {
            let btn = JDButton.init(title:titles[i])
            btn.frame = CGRect(x: CGFloat.init(i) * w, y: 0, width: w, height: frame.size.height)
            btn.addTarget(self, action: #selector(btnAction(_:)), for: .touchUpInside)
            btn.titleLabel?.font = UIFont.systemFont(ofSize: 16)
            btn.tag = 10 + i
            btn.isSelected = false
            scrollView.addSubview(btn)
            scrollView.addSubview(viewLine)

            if self.type == .FontSize {
                btn.backgroundColor = color_nav_red
                btn.setTitleColor(.white, for: .selected)
                btn.setTitleColor(.white, for: .normal)
                if  i == 0 {
                    btn.isSelected = true
                    btn.titleLabel?.font = UIFont.systemFont(ofSize: 18, weight: .medium)
                }
            }
            else if self.type == .TextColor {
                btn.backgroundColor = .white
                btn.setTitleColor(color_nav_red, for: .selected)
                btn.setTitleColor(.black, for: .normal)
                if  i == 0 {
                    btn.isSelected = true
                }
            }
        }
    }
    
    @objc func btnAction(_ btn:UIButton) {
        scrollChangeSelected(index: btn.tag)
    }
    
    func scrollChangeSelected(index:Int) {
        for i in 0..<self.titles.count {
            let v = scrollView.viewWithTag(10 + i)
            let btn = v as! UIButton
            if btn.tag != index {
                btn.isSelected = false
                btn.titleLabel?.font = UIFont.systemFont(ofSize: 16)
            } else {
                btn.isSelected = true
                if self.type == .FontSize {
                    btn.titleLabel?.font = UIFont.systemFont(ofSize: 18, weight: .medium)
                }
                
            }
        }
        
        UIView.animate(withDuration: 0.3) {
            let w:CGFloat = self.frame.size.width / CGFloat.init(self.countOfPage)
            var frameOfLine = self.viewLine.frame
            frameOfLine.origin.x = w * CGFloat.init(index - 10)
            self.viewLine.frame = frameOfLine
            if frameOfLine.origin.x >= screen_width {
                self.scrollView.contentOffset = CGPoint(x: frameOfLine.origin.x - screen_width + w, y: 0)
            }
            if frameOfLine.origin.x <= w {
                self.scrollView.contentOffset = CGPoint(x:0, y: 0)
            }
        }
        
        if delegate != nil {
            delegate?.changeSelected(index:index - 10)
        }
    }
}

【UIPageViewController】

import UIKit

class JDBasePageViewController: UIPageViewController {
    lazy var pageBarView:JDPageBarView = {[unowned self] in
        let v = JDPageBarView.init(frame: CGRect(x: 0, y: 0, width: screen_width, height: button_Height))
        v.delegate = self
        return v
    }()
    
    var allViewControllers: Array<UIViewController>? {
        didSet {
            self.showIndex(index: 0)
        }
    }
    var allTitles:Array<String>? {
        didSet {
            self.pageBarView.titles = allTitles!
        }
    }
     
    convenience  init() {
        self.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
        self.view.addSubview(pageBarView)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.white
        self.dataSource = self
        self.delegate = self
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}
extension JDBasePageViewController {
    func showPage(index: Int) {
        let btn = self.pageBarView.scrollView.viewWithTag(index + 10) as? JDButton
        self.pageBarView.btnAction(btn!)
    }
    
    func showIndex(index:Int) {
        if self.viewControllers?.count == 0 {
            setViewControllers([(allViewControllers?[index])! ], direction:.forward, animated: true, completion: nil)
        } else {
            let page = allViewControllers?.index(of: self.viewControllers![0])
            if page! < index {
                setViewControllers([(allViewControllers?[index])! ], direction:.forward, animated: true, completion: nil)
            }
            else if page! > index {
                setViewControllers([(allViewControllers?[index])! ], direction:.reverse, animated: true, completion: nil)
            }
        }
    }
}

extension JDBasePageViewController:UIPageViewControllerDataSource, UIPageViewControllerDelegate {
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        guard let viewControllerIndex = allViewControllers?.index(of: viewController) else {
            return nil
        }
        
        let previousIndex = viewControllerIndex - 1
        
        guard previousIndex >= 0 else {
            return nil
        }
        
        guard (allViewControllers?.count)! > previousIndex else {
            return nil
        }
        return allViewControllers?[previousIndex]
    }
    
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        
        guard let viewControllerIndex = allViewControllers?.index(of: viewController) else {
            return nil
        }
        
        let nextIndex = viewControllerIndex + 1
        let orderedViewControllersCount = allViewControllers?.count
        
        guard orderedViewControllersCount != nextIndex else {
            return nil
        }
        
        guard orderedViewControllersCount! > nextIndex else {
            return nil
        }
        return allViewControllers?[nextIndex]
    }
    
    func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
        let page = allViewControllers?.index(of: self.viewControllers![0])
        pageBarView.scrollChangeSelected(index: page! + 10)
    }
}

extension JDBasePageViewController:PageBarViewDelegate {
    func changeSelected(index: Int) {
        showIndex(index: index)
    }
}

【使用简单实例】

class JDProductPageViewController: JDBasePageViewController {
    lazy var VCs:Array<ProductViewController> = {[unowned self] in
        let allVC = JDProductViewController()
        allVC.state = "-1"
        
        let onVC = JDProductViewController()
        onVC.state = "2"
        
        let hotVC = JDProductViewController()
        hotVC.state = "1"
        
        let overVC = JDProductViewController()
        overVC.state = "3"
        
        let vcs = [allVC, onVC, hotVC, overVC]
        return vcs
    }()

    override func viewDidLoad() {
        super.viewDidLoad()  
      
        self.pageBarView.type = .FontSize
        self.allViewControllers = VCs
        self.allTitles = ["全部","在售中","预热中","已售罄"]
    }

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

猜你喜欢

热点阅读