swift4.0实现自定义Tabbar,实现按钮中间突出,并且突出部分点击事件响应,主要代码调用如下
**实现思想,
1.中间按钮为继承自button的类,在内部设置中间按钮的图层,
2.其他按钮也是继承UIButton的类设置title和image显示的位置
3.创建一个继承自UIView的类,在这里设置tabbar的排布方式定义协议,方法,供外界调用
4.创建一个继承自UITabBarController的类,在这个类中创建tabbar的元素,
**
`import UIKit
class CQ_TabbarController: UITabBarController {
var lastSelectIndex:NSInteger?
var redPoint:UIView?
var popDelegate:Any?
var composeButton:UIButton?
var CustomTabbar:CQ_Tabbar?
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.tabBar.isHidden = true
self.tabBar.removeFromSuperview()
for childView in self.tabBar.subviews{
if childView .isKind(of: (CQ_Tabbar.self)) {
childView .removeFromSuperview()
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
addChildVC()
setUpTabbar()
}
func setUpTabbar() {
let tabbar = CQ_Tabbar()
tabbar.setItems(items: self.items)
tabbar.Delegate = self
tabbar.backgroundColor = UIColor.init(patternImage: UIImage(named: "tab_backgroundX")!)
tabbar.frame = CGRect(x: 0, y:(ScreenH - CGFloat(TabbarHeight)) , width: ScreenW, height: ScreenH)
view.addSubview(tabbar)
// warning 调用选中的这个方法,必须在初始化设置后在调用,不然会报错
// tabbar.setSelectIndexItem(Index: 1)
CustomTabbar = tabbar
}
func setupButton(){
let rect = self.tabBar.bounds
let w = rect.size.width / CGFloat(self.childViewControllers.count - 1)
composeButton?.frame = rect.insetBy(dx: 2 * w, dy: 0)
composeButton?.height = CGFloat(Int(TabbarHeight))
}
func addChildVC(){
let homeVC = HomeViewController()
addChildVC(childVC: homeVC, title: "首页", imageName: "新闻组管理 (1)", selectedImage: "新闻组管理")
let NewVC = NewViewController()
addChildVC(childVC: NewVC, title: "新闻", imageName: "Push", selectedImage: "PushSele")
let PushVC = PushViewController()
// addChildVC(childVC: PushVC, title: “大发”, imageName: “tab_Irregular”, selectedImage: “tabBar_icon_customer”)
addChildVC(childVC: PushVC, title: "发布", imageName: "添加", selectedImage: "添加")
let DataVC = DataViewController()
addChildVC(childVC: DataVC, title: "发现", imageName: "News", selectedImage: "NewsSele")
let profile = ProfileViewController()
addChildVC(childVC: profile, title: "我的", imageName: "homepage_fill", selectedImage: "homepage_Sele")
}
func addChildVC(childVC:UIViewController,title:NSString,imageName:NSString,selectedImage:NSString){
childVC.tabBarItem.title = title as String
//设置图标
childVC.tabBarItem.image = UIImage(named: imageName as String)
//设置选中的图标
var seleImage = UIImage(named: selectedImage as String)
//不要渲染
seleImage = seleImage?.withRenderingMode(.alwaysOriginal)
childVC.tabBarItem.selectedImage = seleImage;
self.items .add(childVC.tabBarItem)
//添加为tabbar控制器的子控制器
let nav = CQ_NavigationController(rootViewController: childVC)
nav.delegate = self //这个代理方必须写上,代理方法也必须实现
self.addChildViewController(nav)
}
lazy var items:NSMutableArray = {
let array = NSMutableArray()
return array
}()
}
extension CQ_TabbarController:CQTabbarDelegate,UITabBarControllerDelegate,UINavigationControllerDelegate{
func tabbarSelected(tabbar:CQ_Tabbar,clickIndex:NSInteger){
super.selectedIndex = clickIndex
}
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
let Root:UIViewController = navigationController.viewControllers.first!
tabBar.isHidden = true
if viewController != Root {
CustomTabbar?.removeFromSuperview()
var dockFrame = CustomTabbar?.frame
dockFrame?.origin.y = Root.view.height - CGFloat(TabbarHeight)
if Root.view .isKind(of: UIScrollView.self){
let scroller:UIScrollView = Root.view as! UIScrollView
dockFrame?.origin.y += scroller.contentOffset.y
}
CustomTabbar?.frame = dockFrame!
Root.view.addSubview(CustomTabbar!)
}
}
func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
let Root:UIViewController = navigationController.viewControllers.first!
let Nav:CQ_NavigationController = navigationController as! CQ_NavigationController
if viewController == Root {
navigationController.interactivePopGestureRecognizer?.delegate = Nav.PopDelegate as? UIGestureRecognizerDelegate
CustomTabbar?.removeFromSuperview()
CustomTabbar?.frame = CGRect(x: 0.0, y: ScreenH - CGFloat(TabbarHeight), width: ScreenW, height: CGFloat (TabbarHeight))
view .addSubview(CustomTabbar!)
}
}
tabbar的实现部分代码
import UIKit
protocol CQTabbarDelegate:NSObjectProtocol {
func tabbarSelected(tabbar:CQ_Tabbar,clickIndex:NSInteger)
}
class CQ_Tabbar: UIView {
let tabbarTag = 1200
weak var Delegate:CQTabbarDelegate?
var selectedIndex:NSInteger?
var currentSelectedIndex:NSInteger = 0
var subViewCount:NSInteger = 1
var seleButton:UIButton?
var bigButton:CQ_TabbarBigButton?
func setItems(items:NSArray){
for i in 0...count {
let tabbarItem = items[i] as! UITabBarItem
if i == 2 {
//设置中间突出按钮
let BigButton = CQ_TabbarBigButton(type: .custom)
BigButton.tag = self.subviews.count + tabbarTag
BigButton .setImage(tabbarItem.image, for: .normal)
BigButton.adjustsImageWhenHighlighted = false
//设置文字
BigButton.setTitle(tabbarItem.title, for: .normal)
BigButton.setTitleColor(.red, for: .normal)
BigButton.setTitleColor(.green, for: .selected)
BigButton.addTarget(self, action: #selector(btnClick(btn:)), for: .touchDown)
addSubview(BigButton)
bigButton = BigButton
}else
{
let NorButton = CQ_NorTabbarButton(type: .custom)
NorButton.tag = self.subviews.count + tabbarTag
NorButton .setImage(tabbarItem.image, for: .normal)
NorButton.setImage(tabbarItem.selectedImage, for: .selected)
NorButton.adjustsImageWhenHighlighted = false
NorButton.barItem = tabbarItem
NorButton.setTitle(tabbarItem.title, for: .normal)
NorButton.setTitleColor(.red, for: .normal)
NorButton.setTitleColor(.green, for: .selected)
NorButton.addTarget(self, action: #selector(btnClick(btn:)), for: .touchDown)
addSubview(NorButton)
if (self.selectedIndex != nil) {
subViewCount = self.selectedIndex! + 1
}
if (subviews.count == subViewCount) {
selectedIndex = subviews.count - 1
btnClick(btn: NorButton)
}
}
}
}
//留给外界可以设置选中第几个item
public func setSelectIndexItem(Index:NSInteger){
selectedIndex = Index
let button = viewWithTag(tabbarTag + Index)
btnClick(btn: button as! UIButton)
}
//item选中的执行事件
func btnClick(btn:UIButton){
seleButton?.isSelected = false
btn.isSelected = true
seleButton = btn
Delegate?.tabbarSelected(tabbar: self, clickIndex: btn.tag - tabbarTag)
}
override func layoutSubviews() {
super.layoutSubviews()
let Count:NSInteger = subviews.count
var X:CGFloat = 0
var Y:CGFloat = 0
let W:CGFloat = UIScreen.main.bounds.size.width / CGFloat(Count)
var H = 49
for i in 0..
let btn:UIButton = subviews[i] as! UIButton
X = CGFloat(i) * W
//由于第三个按钮上部是突出的所以这里Y上移12
if i == 2 {
Y = -12
H += 12
btn.frame = CGRect(x: X, y: Y, width: W, height: CGFloat(H))
}else
{
//其他按钮正常位置不变
H = 49
Y = 0
btn.frame = CGRect(x: X, y: Y, width: W, height: CGFloat(H))
}
}
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let PointW = 43
let PointH = 61
let PointX = (ScreenW - CGFloat(PointW)) / 2
let PointY = -12
let rect:CGRect = CGRect(x: Int(PointX), y: PointY, width: PointW, height: PointH)
if rect.contains(point) {
return bigButton
}
return super.hitTest(point, with: event)
}
}
上面的代码只是其中一部分,我已将全部代码放到了github上上供下载的github代码下载地址