如果自己可以写的,最好自己写,不要对第三方封装过于依赖。如果他人写的感觉可以,可以借鉴学习,然后自己尝试模仿着去写,如果真的要用,还望学习一下,免得忽然出来个坑,然而自己的一脸茫然。
苹果官方提供了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.
}
}