问题描述
仅当我按索引3时(对于索引0 .. 3 fab.isHidden = true),才会显示如何在中央BUT Fab按钮中创建包含4个项目和一个FAB的“自定义”选项卡栏。如果平移我不需要该按钮的动画,而是填充为加号),仅显示/隐藏。要创建自定义标签栏,请使用本指南https://medium.com/better-programming/draw-a-custom-ios-tabbar-shape-27d298a7f4fa,我需要像这样创建标签栏,我可以尝试enter image description here其他方法,但无法解决问题。
我正尝试这种方式
import UIKit
@IBDesignable
class CustomizedTabBar: UITabBar {
private var shapeLayer: CALayer?
private func addShape() {
let shapeLayer = CAShapeLayer()
shapeLayer.path = createPath()
shapeLayer.strokeColor = UIColor.red.cgColor
shapeLayer.fillColor = UIColor.white.cgColor
shapeLayer.linewidth = 1.0
if let oldShapeLayer = self.shapeLayer {
self.layer.replaceSublayer(oldShapeLayer,with: shapeLayer)
} else {
self.layer.insertSublayer(shapeLayer,at: 0)
}
self.shapeLayer = shapeLayer
}
override func draw(_ rect: CGRect) {
self.addShape()
}
func createPath() -> CGPath {
let height: CGFloat = 37.0
let path = UIBezierPath()
let centerWidth = self.frame.width / 2
path.move(to: CGPoint(x: 0,y: 0)) // start top left
path.addLine(to: CGPoint(x: (centerWidth - height * 2),y: 0)) // the beginning of the trough
//// // first curve down
// path.addCurve(to: CGPoint(x: centerWidth,y: height),controlPoint1: CGPoint(x: (centerWidth - 25),y: 0),controlPoint2: CGPoint(x: centerWidth - 35,y: height))
//
//// // second curve up
// path.addCurve(to: CGPoint(x: (centerWidth + height * 1.0),// controlPoint1: CGPoint(x: centerWidth + 25,controlPoint2: CGPoint(x: (centerWidth + 30),y: 0))
// cirle inside tab bar
path.addArc(withCenter: CGPoint(x: centerWidth,radius: height,startAngle: CGFloat(180).degreesToradians,endAngle: CGFloat(0).degreesToradians,clockwise: false)
// complete the rect
path.addLine(to: CGPoint(x: self.frame.width,y: 0))
path.addLine(to: CGPoint(x: self.frame.width,y: self.frame.height))
path.addLine(to: CGPoint(x: 0,y: self.frame.height))
path.close()
return path.cgPath
}
override func point(inside point: CGPoint,with event: UIEvent?) -> Bool {
let buttonRadius: CGFloat = 35
return abs(self.center.x - point.x) > buttonRadius || abs(point.y) > buttonRadius
}
func createPathCircle() -> CGPath {
let radius: CGFloat = 37.0
let path = UIBezierPath()
let centerWidth = self.frame.width / 2
path.move(to: CGPoint(x: 0,y: 0))
path.addLine(to: CGPoint(x: (centerWidth - radius * 2),y: 0))
path.addArc(withCenter: CGPoint(x: centerWidth,radius: radius,clockwise: false)
path.addLine(to: CGPoint(x: self.frame.width,y: self.frame.height))
path.close()
return path.cgPath
}
}
extension CGFloat {
var degreesToradians: CGFloat { return self * .pi / 180 }
var radiansTodegrees: CGFloat { return self * 180 / .pi }
}
第二种方式
import UIKit
class MainTabBar: UITabBar {
var checkState: Bool = true
public var middleButton = UIButton()
override func awakeFromNib() {
super.awakeFromNib()
guard let tabItems = items else { return }
tabItems[1].titlePositionAdjustment = UIOffset(horizontal: -10,vertical: 0)
tabItems[2].titlePositionAdjustment = UIOffset(horizontal: 10,vertical: 0)
setupMiddleButton()
}
override func hitTest(_ point: CGPoint,with event: UIEvent?) -> UIView? {
if self.isHidden {
return super.hitTest(point,with: event)
}
let from = point
let to = middleButton.center
return sqrt((from.x - to.x) * (from.x - to.x) + (from.y - to.y) * (from.y - to.y)) <= 39 ? middleButton : super.hitTest(point,with: event)
}
override func layoutSubviews() {
super.layoutSubviews()
middleButton.center = CGPoint(x: UIScreen.main.bounds.width / 2,y: 5)
}
func setupMiddleButton() {
middleButton.frame.size = CGSize(width: 70,height: 70)
middleButton.layer.cornerRadius = 35
middleButton.layer.masksToBounds = true
middleButton.layer.borderWidth = 8
middleButton.layer.borderColor = #colorLiteral(red: 1.0,green: 1.0,blue: 1.0,alpha: 1.0)
middleButton.backgroundColor = #colorLiteral(red: 0.2447069331,green: 0.850134835,blue: 0.1531122658,alpha: 1)
middleButton.setimage(UIImage(named: "plus.png"),for: .normal)
middleButton.center = CGPoint(x: UIScreen.main.bounds.width / 2,y: 0)
middleButton.addTarget(self,action: #selector(test),for: .touchUpInside)
addSubview(middleButton)
}
@objc func test() {
print("my name is jeff")
}
}
我从文章中尝试这种方式
https://equaleyes.com/blog/2017/09/04/the-common-raised-center-button-problems-in-tabbar/
但这对我不起作用,而且我从WWW上读取了太多信息,但没有得到答案(
解决方法
我是创建此标签栏的,我们只需几个步骤。 创建ViewController并嵌入到“ TabBarController”中,然后需要首先为“ UITabBar”创建两个类,该类包含形状和您想要的“ UITabBar”,第二个类为“ UITabBarController”,以便在其中可以添加动画的ViewController之间进行切换... 。这是因为我的TabBar有4个选项卡,并且仅在LAST选项卡上具有带有动画的Central FAB按钮,并且当出现按钮时,我应该为2和3 ui选项卡栏元素设置位置动画。
“ UITabBar”的类
import UIKit
@IBDesignable
class CustomizedTabBar: UITabBar {
// MARK:- Variables -
@objc public var centerButtonActionHandler: ()-> () = {}
@IBInspectable public var centerButton: UIButton?
@IBInspectable public var centerButtonColor: UIColor?
@IBInspectable public var centerButtonHeight: CGFloat = 50.0
@IBInspectable public var padding: CGFloat = 5.0
@IBInspectable public var buttonImage: UIImage?
@IBInspectable public var buttonTitle: String?
@IBInspectable public var tabbarColor: UIColor = UIColor.lightGray
@IBInspectable public var unselectedItemColor: UIColor = .init(red: 0.58,green: 0.61,blue: 0.66,alpha: 1.0)
@IBInspectable public var selectedItemColor: UIColor = UIColor.black
public var arc: Bool = true {
didSet {
self.setNeedsDisplay()
}
}
private var shapeLayer: CALayer?
private func addShape() {
let shapeLayer = CAShapeLayer()
shapeLayer.path = createPath()
shapeLayer.strokeColor = UIColor.white.cgColor
shapeLayer.fillColor = #colorLiteral(red: 0.96,green: 0.96,blue: 0.96,alpha: 1)
shapeLayer.lineWidth = 1.0
if let oldShapeLayer = self.shapeLayer {
self.layer.replaceSublayer(oldShapeLayer,with: shapeLayer)
} else {
self.layer.insertSublayer(shapeLayer,at: 0)
}
self.shapeLayer = shapeLayer
self.tintColor = centerButtonColor
self.unselectedItemTintColor = unselectedItemColor
self.tintColor = selectedItemColor
self.setupMiddleButton()
}
override func draw(_ rect: CGRect) {
self.addShape()
}
override public func hitTest(_ point: CGPoint,with event: UIEvent?) -> UIView? {
guard !clipsToBounds && !isHidden && alpha > 0 else { return nil }
for member in subviews.reversed() {
let subPoint = member.convert(point,from: self)
guard let result = member.hitTest(subPoint,with: event) else { continue }
return result
}
return nil
}
func createPath() -> CGPath {
let padding: CGFloat = 5.0
let centerButtonHeight: CGFloat = 53.0
let f = CGFloat(centerButtonHeight / 2.0) + padding
let h = frame.height
let w = frame.width
let halfW = frame.width/2.0
let r = CGFloat(18)
let path = UIBezierPath()
path.move(to: .zero)
if (!arc) {
path.addLine(to: CGPoint(x: halfW-f-(r/2.0),y: 0))
path.addQuadCurve(to: CGPoint(x: halfW-f,y: (r/2.0)),controlPoint: CGPoint(x: halfW-f,y: 0))
path.addArc(withCenter: CGPoint(x: halfW,radius: f,startAngle: .pi,endAngle: 0,clockwise: false)
path.addQuadCurve(to: CGPoint(x: halfW+f+(r/2.0),y: 0),controlPoint: CGPoint(x: halfW+f,y: 0))
}
path.addLine(to: CGPoint(x: w,y: 0))
path.addLine(to: CGPoint(x: w,y: h))
path.addLine(to: CGPoint(x: 0.0,y: h))
path.close()
return path.cgPath
}
private func setupMiddleButton() {
centerButton = UIButton(frame: CGRect(x: (self.bounds.width / 2)-(centerButtonHeight/2),y: -16,width: centerButtonHeight,height: centerButtonHeight))
centerButton!.setNeedsDisplay()
centerButton!.layer.cornerRadius = centerButton!.frame.size.width / 2.0
centerButton!.setTitle(buttonTitle,for: .normal)
centerButton!.setImage(UIImage(named: "plus"),for: .normal)
centerButton!.backgroundColor = .init(red: 0.07,green: 0.83,blue: 0.05,alpha: 1.0)
centerButton!.tintColor = UIColor.white
self.centerButton!.isHidden = true
if (!self.arc) {
DispatchQueue.main.async {
UIView.transition(with: self.centerButton!,duration: 1,options: .transitionCrossDissolve,animations: {
self.centerButton!.isHidden = false
})
}
}
//add to the tabbar and add click event
self.addSubview(centerButton!)
centerButton!.addTarget(self,action: #selector(self.centerButtonAction),for: .touchUpInside)
}
override func point(inside point: CGPoint,with event: UIEvent?) -> Bool {
let buttonRadius: CGFloat = 35
return abs(self.center.x - point.x) > buttonRadius || abs(point.y) > buttonRadius
}
func createPathCircle() -> CGPath {
let radius: CGFloat = 37.0
let path = UIBezierPath()
let centerWidth = self.frame.width / 2
path.move(to: CGPoint(x: 0,y: 0))
path.addLine(to: CGPoint(x: (centerWidth - radius * 2),y: 0))
path.addArc(withCenter: CGPoint(x: centerWidth,radius: radius,startAngle: CGFloat(180).degreesToRadians,endAngle: CGFloat(0).degreesToRadians,clockwise: false)
path.addLine(to: CGPoint(x: self.frame.width,y: 0))
path.addLine(to: CGPoint(x: self.frame.width,y: self.frame.height))
path.addLine(to: CGPoint(x: 0,y: self.frame.height))
path.close()
return path.cgPath
}
// Menu Button Touch Action
@objc func centerButtonAction(sender: UIButton) {
self.centerButtonActionHandler()
}
}
extension CGFloat {
var degreesToRadians: CGFloat { return self * .pi / 180 }
var radiansToDegrees: CGFloat { return self * 180 / .pi }
}
以及UITabBarController的类
导入UIKit
class MyTabBarController: UITabBarController {
override func tabBar(_ tabBar: UITabBar,didSelect item: UITabBarItem) {
let myTabBar = tabBar as! CustomizedTabBar
if (myTabBar.items?[3] == item) {
myTabBar.arc = false
} else {
myTabBar.arc = true
}
}
}