也是项目中常遇到的菜单栏之一,万恶的Xcode居然不出个系统控件(话说,安卓是有的)具体效果如下 ,
本文的内容就是对上述控件的简单封装,代码都是写在继承自UIViewController的自定义控制器里。
1.先把变量贴出来,方便大家观看代码
let kNavigationBarHeight = CGFloat(64.0)
let kTabbarHeight = CGFloat(49.0)
let KUIScreenSize = UIScreen.main.bounds.size
let KUIScreenWidth = CGFloat(KUIScreenSize.width)
let KUIScreenHeight = CGFloat(KUIScreenSize.height)
let BottomBGColor = UIColor(red: 242/255.0, green: 242/255.0, blue: 242/255.0, alpha:1.0)
fileprivate let baseTopBtnTag = 988
fileprivate var currentButton = UIButton()
fileprivate let topBackView = UIView()
fileprivate let normalTextColor = RGBColor(89, g: 89, b: 89)
fileprivate let selectedTextColor = RGBColor(255, g: 81, b: 93)
fileprivate let btnHeight: CGFloat = 39
fileprivate let bottomHeight: CGFloat = 1
fileprivate let sliderHeight: CGFloat = 2
fileprivate let selectedBgImage = UIImage(named: "bg_drakBlue")
fileprivate let sliderView = UIView()
var mainScrollView = UIScrollView()
var currentOffset = CGPoint()
let backViewHeight: CGFloat = 40.0
var isDefaultTitle = Bool()
var titleArray = [String](){
didSet{
setBtnAndSplitLineWithTitleArray(titleArray)
}
}
2.创建一个作为父视图的scrollView
func setupMainScrollView(){
let scrollView = UIScrollView(frame: CGRect(x: 0, y: backViewHeight, width: KUIScreenWidth, height: KUIScreenHeight - backViewHeight - kNavigationBarHeight))
scrollView.isPagingEnabled = true;
scrollView.delegate = self;
scrollView.showsHorizontalScrollIndicator = false;
scrollView.showsVerticalScrollIndicator = false;
//初始化滑动视图的偏移量
scrollView.contentOffset = currentOffset;
view.addSubview(scrollView)
mainScrollView = scrollView;
}
3.创建顶部菜单视图
func setTopView(){
currentOffset = CGPoint(x: 0, y: 0)
topBackView.frame = CGRect(x: 0, y: 0, width: KUIScreenWidth, height: backViewHeight)
topBackView.backgroundColor = UIColor.white
topBackView.isUserInteractionEnabled = true
view.addSubview(topBackView)
}
4.底部选择菜单的水平条
func setBtnBottomLine(){
let bottomLine = UIView(frame: CGRect(x: 0, y: backViewHeight-bottomHeight, width: KUIScreenWidth, height: bottomHeight))
bottomLine.backgroundColor = BottomBGColor
topBackView.addSubview(bottomLine)
}
5.(重点)通过判断传入的数组的个数确定选项布局
func setBtnAndSplitLineWithTitleArray(_ titlesArray: [String]){
let btnWidth = KUIScreenWidth / CGFloat(titlesArray.count)
//底部选择的红色水平线
sliderView.backgroundColor = selectedTextColor
for i in 0 ..< titlesArray.count {
//选项按钮
let btn = setBtnWithIndex(i, btnWidth: btnWidth,titlesArray: titlesArray)
if i == 0{
btn.isSelected = true
currentButton = btn
sliderView.frame = CGRect(x: 0, y: backViewHeight - sliderHeight, width: btnWidth, height: sliderHeight)
topBackView.addSubview(sliderView)
}
topBackView.addSubview(btn)
}
mainScrollView.contentSize = CGSize(width: CGFloat(titlesArray.count) * KUIScreenWidth, height: 0)
}
//创建选项按钮
func setBtnWithIndex(_ i: Int,btnWidth: CGFloat,titlesArray: [String])->UIButton{
let btnFrame = CGRect(x: CGFloat(i)*btnWidth, y: 0, width: btnWidth, height: backViewHeight - sliderHeight)
let btn = UIButton(type: UIButtonType.custom)
btn.frame = btnFrame
btn.backgroundColor = UIColor.clear
btn.titleLabel?.font = UIFont.systemFont(ofSize: 16)
btn.setTitle(titlesArray[i] , for: UIControlState())
btn.setTitleColor(normalTextColor, for: UIControlState())
btn.setTitleColor(selectedTextColor, for: UIControlState.selected)
btn.setBackgroundImage(selectedBgImage, for: UIControlState.selected)
btn.tag = i + baseTopBtnTag
btn.addTarget(self, action: #selector(SlidePageViewController.slideBtnClick(_:)), for: UIControlEvents.touchUpInside)
return btn
}
//选项按钮的点击事件
func slideBtnClick(_ sender: UIButton){
if sender == currentButton{
return
}else{
currentButton.isSelected = false;
sender.isSelected = !sender.isSelected;
currentButton = sender;
UIView.animate(withDuration: 0.3, animations: { () -> Void in
self.mainScrollView.contentOffset=CGPoint(x: CGFloat(sender.tag - self.baseTopBtnTag) * KUIScreenWidth, y: 0);
self.sliderView.center.x = self.currentButton.center.x
})
}
}
6.scrollView的代理方法控制左滑右滑切换控制器
//MARK:UIScrollViewDelegate
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let index = Int(mainScrollView.contentOffset.x/KUIScreenWidth)
if index >= 0 && index < titleArray.count{
let btn = view.viewWithTag(index+baseTopBtnTag) as! UIButton
slideBtnClick(btn)
}
}
7.控制器生命周期控制滑动视图偏移量
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
mainScrollView.contentOffset = currentOffset
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
currentOffset = mainScrollView.contentOffset
}
至此,控件封装算是完成了,需要使用时创建一个控制器继承我们所封装的控制器
(1)先确定titleArray的值, 也就是水平菜单栏上有多少个选项
override func viewDidLoad() {
super.viewDidLoad()
titleArray = ["全部", "进行中","已揭晓"]
setChildVC()
}
(2)添加子控制器和子视图
func setChildVC(){
let orderDynamicVC = ShoppingRecordViewController()
orderDynamicVC.view.frame = CGRect(x: 0, y: 0, width: mainScrollView.frame.size.width, height: mainScrollView.frame.size.height)
orderDynamicVC.type = UITableViewShowtype.byAll;
addChildViewController(orderDynamicVC)
mainScrollView.addSubview(orderDynamicVC.view)
let systemNotifyVC = ShoppingRecordViewController()
systemNotifyVC.view.frame = CGRect(x: KUIScreenWidth, y: 0, width: mainScrollView.frame.size.width, height: mainScrollView.frame.size.height)
systemNotifyVC.type = UITableViewShowtype.byLoading
addChildViewController(systemNotifyVC)
mainScrollView.addSubview(systemNotifyVC.view)
let systemNotify = ShoppingRecordViewController()
systemNotify.view.frame = CGRect(x: KUIScreenWidth*2, y: 0, width: mainScrollView.frame.size.width, height: mainScrollView.frame.size.height)
systemNotify.type = UITableViewShowtype.byPast
addChildViewController(systemNotify)
mainScrollView.addSubview(systemNotify.view)
}
因为只是简单的封装,感觉使用时候写的代码还是有点多。。。。