TabBarController是項(xiàng)目主要框架結(jié)構(gòu), 一般來說系統(tǒng)自帶的TabBarController已足夠使用, 但是要實(shí)現(xiàn)一些產(chǎn)品的需求,有時(shí)候就需要我們自定義一個(gè)TabBarController俗慈,本篇文章將為您講述如何使用Swift自定義TabBarController.順便附上Demo地址
github.com/15395401361/LFTabBarContoller
首先:定制TabBar上面的按鈕江耀。
//
//? LFCustomButtonItem.swift
//? LFTabBarDemo
//
//? Created by 吳林豐 on 2017/3/20.
//? Copyright ? 2017年 吳林豐. All rights reserved.
//
import UIKit
class LFCustomButtonItem: UIButton {
// MARK: - 頁面所用屬性
private let itemWH = 40? //item的大小
private let itemTitleColor = UIColor.colorWithHexString(hex: "7b7b7b") //item? 中默認(rèn)的字體顏色
private let selectedItemTitleColor = UIColor.colorWithHexString(hex: "e2231a")? //item中被選中是字體的顏色
private let itemTitleFont = UIFont.systemFont(ofSize: 10) //item中字體的大小
private let badgeValueViewImageName = "badge_one@2x.png" //提醒背景圖片
private let badgeValueViewImageNameMore = "badge_more@2x.png" //更多背景提醒
private let badgeValueFont = UIFont.systemFont(ofSize: 12)
private let badgeValueColor = UIColor.white
private var badgeValueViewWH:CGFloat{
get{
//? ? ? ? ? ? return CGFloat(itemWH) * 0.15 //如果只是紅點(diǎn)提示,則返回此大小
return CGFloat(itemWH) * 0.45? //如果顯示數(shù)字掸鹅,則返回這個(gè)大小
}
}
private let KSImageScale:CGFloat = 1
// MARK: - 懶加載紅點(diǎn)
lazy var badgeValueView:UIButton = {
let x:CGFloat = self.frame.size.width/2+10
let y:CGFloat = 5
//? ? ? ? let x:CGFloat = self.frame.size.width/2+5
//? ? ? ? let y:CGFloat = 3 只是小紅點(diǎn)提示的時(shí)候,常量值為這個(gè)
let badgeValueView:UIButton = UIButton.init(frame: CGRect.init(origin: CGPoint.init(x: x, y: y), size: CGSize.init(width: self.badgeValueViewWH, height: self.badgeValueViewWH)))
badgeValueView.setBackgroundImage(UIImage.init(named: self.badgeValueViewImageName), for: .normal)
badgeValueView.setTitleColor(self.badgeValueColor, for: UIControlState.normal)
badgeValueView.adjustsImageWhenHighlighted = false
badgeValueView.isHidden = true
badgeValueView.titleLabel?.font = UIFont.systemFont(ofSize: 12)
return badgeValueView
}()
// MARK: - 初始化self
init(_ frame: CGRect,_ norImage:String,_ selectImage:String,_ titile:String) {
super.init(frame: frame)
//頂部圖片
self.imageView?.contentMode = .center
self.setImage(UIImage.init(named: norImage), for: .normal)
self.setImage(UIImage.init(named: selectImage), for: .selected)
self.setImage(UIImage.init(named: norImage), for: .highlighted)
//設(shè)置文字
self.titleLabel?.textAlignment = .center
self.setTitle(titile, for: .normal)
self.setTitleColor(itemTitleColor, for: .normal)
self.setTitleColor(itemTitleColor, for: .highlighted)
self.setTitleColor(selectedItemTitleColor, for: .selected)
self.titleLabel?.font = itemTitleFont
self.addSubview(self.badgeValueView)
}
// MARK: - 設(shè)置提醒小紅點(diǎn)的數(shù)量
func setItemBadgeNumber(_ number:Int){
if number != 0 {
if? self.badgeValueView.isHidden == true {
self.badgeValueView.isHidden = false
}
/**
實(shí)現(xiàn)紅點(diǎn)及數(shù)字提醒
*/
let tabBadgeNum:String = number > 99 ? "...":"\(number)"
self.badgeValueView.setTitle(tabBadgeNum, for: .normal)
let tabBadgeStr:String = "\(number)"
let longImage:UIImage = UIImage.resizableImage(imageName: badgeValueViewImageName)
self.badgeValueView.setBackgroundImage(longImage, for: .normal)
var newframe:CGRect = self.badgeValueView.frame
if (tabBadgeStr as NSString).length > 1 {
newframe.size.width = badgeValueViewWH + 4
self.badgeValueView.frame = newframe
}else{
newframe.size.width = badgeValueViewWH
self.badgeValueView.frame = newframe
}
/**
只實(shí)現(xiàn)紅點(diǎn)提醒,不實(shí)現(xiàn)數(shù)字提醒
同上方的方法二者選一
*/
//? ? ? ? ? ? self.badgeValueView.setBackgroundImage(UIImage.init(named: "TabBarEdgeImage"), for: .normal)
}else{
self.badgeValueView.isHidden = true
}
}
//重寫系統(tǒng)方法雹熬,設(shè)置按鈕內(nèi)部圖片和文字的位置
override func imageRect(forContentRect contentRect: CGRect) -> CGRect {
let W:CGFloat = contentRect.size.width
let H:CGFloat = contentRect.size.height * KSImageScale
return CGRect.init(x: 0, y: -5, width: W, height: H)
}
override func titleRect(forContentRect contentRect: CGRect) -> CGRect {
let W:CGFloat = contentRect.size.width
let H:CGFloat = contentRect.size.height * KSImageScale
let Y:CGFloat = contentRect.size.height - H
return CGRect.init(x: 0, y: Y+15, width: W, height: H)
}
//這個(gè)是用于Storyboard 的错维。蘋果由于主推SB,所以要求必須實(shí)現(xiàn)此方法
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
第二步橄唬,繼承TabBarController赋焕,開始定制自己項(xiàng)目的TabBarController,并編寫項(xiàng)目中所要用到的方法仰楚。
//
//? LFCustomTabBarController.swift
//? LFTabBarDemo
//
//? Created by 吳林豐 on 2017/3/20.
//? Copyright ? 2017年 吳林豐. All rights reserved.
//
import UIKit
class LFCustomTabBarController: UITabBarController {
var currentSelectedIndex:NSInteger? //當(dāng)前選中的button的index
var buttons = [LFCustomButtonItem]()
let ScreenWidth = kScreenWidth
lazy var objectNavis:[UINavigationController] = {
var navis = [UINavigationController]()
navis = self.viewControllers as! [UINavigationController]
return navis
}()
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.customTabBar()
}
func customTabBar(){
//初始化TabBar上的Item數(shù)量和Item上的標(biāo)題隆判,圖片等等
let normalImageArr = NSArray.init(array: ["out-call","patientsNormal","personalCenterNormal"])
let selectedImageArray = NSArray.init(array: ["out-callSelected","patientsSelected","personalCenterSelected"])
let titleArr = NSArray.init(array: ["首頁","聯(lián)系人","個(gè)人中心"])
let viewCount:Int = (self.viewControllers?.count)! > 5 ? 5:(self.viewControllers?.count)!
let _width:CGFloat = kScreenWidth / CGFloat(viewCount)
let _height:CGFloat = self.tabBar.frame.size.height
for i in 0 ..< (self.viewControllers?.count)!{
let btn:LFCustomButtonItem = LFCustomButtonItem.init(CGRect.init(x: CGFloat(i) * _width, y: 0, width: _width, height: _height), normalImageArr[i] as! String, selectedImageArray[i] as! String, titleArr[i] as! String)
btn.addTarget(self, action: #selector(selectedTab(_:)), for: UIControlEvents.touchUpInside)
btn.tag = i
self.buttons.append(btn)
self.tabBar.addSubview(btn)
}
//默認(rèn)選中第一個(gè)頁面
if self.buttons.count > 0 {
self.buttons[0].isSelected = true
self.selectedTab(self.buttons[0])
}
}
// MARK - 設(shè)置消息數(shù)量
//設(shè)置消息數(shù)
func setBadgeNumber(_ number:NSInteger,_ index:NSInteger){
let? buttonItem:LFCustomButtonItem = self.buttons[index]
buttonItem.setItemBadgeNumber(number)
}
func pushToHome(){
for bt in self.buttons {
if bt.tag == 0 {
bt.isSelected = true
}else{
bt.isSelected = false
}
}
self.selectedIndex = 0
let nav:UINavigationController = self.objectNavis[0]
nav.popToRootViewController(animated: true)
}
//其他頁面調(diào)用選擇按鈕
func selectedTab(_ button:UIButton){
if self.currentSelectedIndex == button.tag{
return
}
for bt in self.buttons{
if bt == button {
bt.isSelected = true
}else{
bt.isSelected = false
}
}
self.currentSelectedIndex = button.tag
self.selectedIndex = self.currentSelectedIndex!
//選中一級界面
if self.selectedIndex != 0 && (self.viewControllers?.count)! > self.selectedIndex? {
/**
注意此處的跳轉(zhuǎn)
由于系統(tǒng)的TabBarController上的viewCoutrollers 默認(rèn)為繼承的是UIViewController
所以,如果使用自定義的導(dǎo)航欄去加載ViewControllers作為TabBarControlelr的viewCoutrollers時(shí)
此處需要進(jìn)行類型轉(zhuǎn)換僧界,從而順利進(jìn)行跳轉(zhuǎn)侨嘀。
*/
if self.objectNavis.count > 0{
//此處需要將其轉(zhuǎn)為具有導(dǎo)航功能的navigationController
(self.selectedViewController as! UINavigationController).popToRootViewController(animated: true)
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
1. 如何進(jìn)行頁面切換
自定義的TabBarController繼承自系統(tǒng), 所以還是直接用系統(tǒng)的selectedIndex屬性來實(shí)現(xiàn),?
2. 自定義的幾個(gè)Button如何只選中一個(gè), 以及選中狀態(tài)的切換?
定義一個(gè)currentSelectedIndex,標(biāo)示表示選中的button按鈕捂襟。
3.如何使用
通過上面的封裝可以實(shí)現(xiàn)傳入數(shù)據(jù)源,初始化tabBarController,并且支持角標(biāo)及小紅點(diǎn),很方便在今后項(xiàng)目中調(diào)用.喜歡的話咬腕,給個(gè)星星,你們的支持就是我們筆者的動(dòng)力葬荷。謝謝涨共。?