//
// PDLinkageView.swift
// ShenKang
//
// Created by 裴铎 on 2019/4/29.
// Copyright © 2019 apple. All rights reserved.
//
import UIKit
import RxSwift
import RxCocoa
class PDLinkageView: UIView {
///标题s数组
var titles : [String] = [String]()
/** 存放子控制器对象的数组,内部的元素个数必须和标题数组内的一致 */
var allViewControllers : [UIViewController] = [UIViewController]()
///上一次被点击的按钮
fileprivate var previousClickButton = UIButton()
///默认选中的按钮d下标
fileprivate var defaultButtonIndex : Int = 0
///空间标识符
fileprivate let identifierTag = 2019429 //2019/4/29.
///垃圾袋
fileprivate lazy var bag = DisposeBag()
///下划线的默认宽度
fileprivate let titleUnderlineWidth : CGFloat = 30
///标题视图
lazy var titlesView : UIView = {
let titlesView = UIView(frame: CGRect(x: 0, y: 0, width: self.pd_width, height: 44))
titlesView.backgroundColor = .white
/** 获取应该添加的按钮个数 */
let buttonCount : CGFloat = CGFloat(self.titles.count);
/** 循环添加按钮 */
for (index, title) in self.titles.enumerated() {
let button = UIButton(type: .custom)
let buttonWidth = titlesView.pd_width / buttonCount
button.frame = CGRect(x: CGFloat(index) * buttonWidth, y: 0, width: buttonWidth, height: titlesView.pd_height)
button.setTitle(title, for: .normal)
button.setTitleColor(UIColor.black, for: .normal)
button.setTitleColor(UIColor.blue, for: .selected)
button.tag = index + self.identifierTag
button.rx.tap.subscribe(onNext: {[weak self] (_) in
self?.titleButtonClick(button: button)
}).disposed(by: self.bag)
titlesView.addSubview(button)
}
return titlesView
}()
///下划线
lazy var titleUnderline : UIView = {
let titleUnderline = UIView()
/** 拿到标题视图上的某一个按钮, 用来获取按钮上的状态信息 */
guard let button = self.titlesView.subviews.first as? UIButton else {
return titleUnderline
}
titleUnderline.backgroundColor = button.titleColor(for: .selected)
titleUnderline.pd_height = 2
titleUnderline.pd_width = button.titleLabel?.pd_width ?? self.titleUnderlineWidth
titleUnderline.pd_y = button.pd_height - 2
titleUnderline.pd_centerX = self.titlesView.subviews[self.defaultButtonIndex].pd_centerX
return titleUnderline
}()
///主体滚动视图
lazy var mainScrollView : UIScrollView = {
let mainScrollView = UIScrollView(frame: CGRect(x: 0, y: self.titlesView.pd_bottom, width: self.pd_width, height: self.pd_height - self.titlesView.pd_height))
mainScrollView.backgroundColor = UIColor.gray
mainScrollView.contentSize = CGSize(width: self.pd_width * CGFloat(self.titles.count), height: self.pd_height - self.titlesView.pd_height)
mainScrollView.isPagingEnabled = true
mainScrollView.delegate = self
mainScrollView.scrollsToTop = false
mainScrollView.showsVerticalScrollIndicator = false
mainScrollView.showsHorizontalScrollIndicator = false
mainScrollView.contentOffset = CGPoint(x: self.pd_width * CGFloat(self.defaultButtonIndex), y: 0)
return mainScrollView
}()
}
// MARK:- 自定义构造器
extension PDLinkageView {
/// 自定义构造器
///
/// - Parameters:
/// - frame: 尺寸位置
/// - titles: 标题按钮显示文字数组
/// - allViewControllers: 所有的子控制器(和标题数组的元素个数要相同)
/// - defaultButtonIndex: 默认选中的按钮下标 默认:0
convenience init(frame: CGRect, titles : [String], allViewControllers : [UIViewController], _ defaultButtonIndex : Int = 0) {
self.init(frame: frame)
self.titles = titles
self.allViewControllers = allViewControllers
self.defaultButtonIndex = defaultButtonIndex
guard titles.count > 0 else {
fatalError("titles不能为空")
}
guard titles.count == allViewControllers.count else {
fatalError("标题按钮和s实际的子控制器个数不相同")
}
guard defaultButtonIndex < titles.count else {
fatalError("默认选中的按钮下标越界")
}
self.setUI()
}
}
// MARK:- UI
extension PDLinkageView {
fileprivate func setUI() {
self.addSubview(titlesView)
self.addSubview(titleUnderline)
self.addSubview(mainScrollView)
let button = titlesView.subviews[defaultButtonIndex] as! UIButton
titleButtonClick(button: button)
}
///加载子控制器视图
fileprivate func setupChildViewController(index : Int){
guard allViewControllers.count > 0 else {
return;/** 没有子控制器时不要执行下面的代码 */
}
/** 获取到索引对应的子控制器 */
let childVC = allViewControllers[index]
/** 判断控制器是否被加载过 */
guard childVC.isViewLoaded == false else {
return
}
/** 获取子控制器的视图 */
guard let childView = childVC.view else {
return
}
/** 判断视图是否被加载过,判断childView是否有父控件,如果有说明被加载过 */
guard childView.superview == nil else {
return
}
guard childView.window == nil else {
return
}
/** 设置视图的frame */
childView.frame = mainScrollView.bounds;
/** 加载到滚动视图上 */
mainScrollView.addSubview(childView)
}
}
// MARK:- 事件
extension PDLinkageView {
func titleButtonClick(button : UIButton) {
/** 取消上一次点击的按钮选中状态 */
previousClickButton.isSelected = false
button.isSelected = true
previousClickButton = button
let index = button.tag - self.identifierTag
UIView.animate(withDuration: 0.25, animations: {
self.titleUnderline.pd_width = button.titleLabel?.pd_width ?? self.titleUnderlineWidth
self.titleUnderline.pd_centerX = button.pd_centerX
let offsetX = self.mainScrollView.pd_width * CGFloat(index)
self.mainScrollView.contentOffset = CGPoint(x: offsetX, y: self.mainScrollView.contentOffset.y)
}) { (finish) in
self.setupChildViewController(index: index)
}
}
}
// MARK:- 滚动视图代理协议
extension PDLinkageView : UIScrollViewDelegate {
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
/** 求出应该点击的按钮的索引 */
let index = scrollView.contentOffset.x / scrollView.pd_width;
let button = titlesView.subviews[Int(index)] as! UIButton
titleButtonClick(button: button)
}
}
iOS-Swift分类视图
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 前言 前段时间一直在做项目,没时间将项目中遇到的东西、问题、代码整理起来,现在空下来了,赶紧整理一下,前面的项目中...
- 根据网上的一些资料,封装了一套完美的瀑布流分类,下面看源码吧下面是JYWaterfallLayout.h头文件 接...
- 概述 一般的页面分类展示,都类似于今日头条等新闻app那样,顶部一个分类控制器,内容列表支持左右滑动切换。但是对于...
- 在本课中,你将继续使用FoodTracker应用的菜品场景的UI。你将重新排列现有的用户界面元素,并使用一个ima...
- 萍姐是我朋友的合作伙伴,有天,朋友去她们办公室办事儿,正好听到她在茶水间里,和公司的小姑娘在说“卢璐”。 然后我们...