Skip to content

Instantly share code, notes, and snippets.

@phuongddx
Created July 4, 2020 15:50
Show Gist options
  • Save phuongddx/ff3771bcee4caf4dc31fd23d40a94da1 to your computer and use it in GitHub Desktop.
Save phuongddx/ff3771bcee4caf4dc31fd23d40a94da1 to your computer and use it in GitHub Desktop.
//
// HomeTabbar.swift
// Alamofire
//
// Created by DoanDuyPhuong on 6/29/20.
//
import Foundation
import UIKit
@IBDesignable
class HomeTabBar: UITabBar {
let curveTop: CGFloat = 20
let widthItem = ViewService.screenSize().width / 5
// var curveRadius: CGFloat {
// let height = self.frame.height * getAlpha() - self.getSafeBottom()
// return (height / 2) + curveTop
//// return 42
// }
var curveRadius: CGFloat {
// let height = self.frame.height * getAlpha() - self.getSafeBottom()
return (widthItem / 2) + curveTop
}
var shapLayer: CAShapeLayer?
var circleLayer: CAShapeLayer?
// var circleYellowRadius: CGFloat {
//// return self.curveRadius
// let height = self.frame.height - self.getSafeBottom()
// return ((height / 2) + curveTop) * 2 / 4
//// return 70
// }
private func getAlpha() -> CGFloat {
return 2 / 3
}
private func getCircleYellowRadius() -> CGFloat {
return self.curveRadius * 4 / 5
}
override func draw(_ rect: CGRect) {
self.addShape()
self.addYellowCicle()
insertSeparatorLineView()
// setupCenterTabbarItem()
self.unselectedItemTintColor = .white
}
private func addShape() {
let shape = CAShapeLayer()
shape.path = self.createPath()
shape.strokeColor = UIColor.init(0x1D1D1D).cgColor
shape.fillColor = UIColor.init(0x1D1D1D).cgColor
shape.lineWidth = 0
if let s = self.shapLayer {
self.layer.replaceSublayer(s, with: shape)
}
else {
self.layer.insertSublayer(shape, at: 0)
}
self.shapLayer = shape
}
private func createPath() -> CGPath {
// https://stackoverflow.com/questions/22212440/using-math-class-to-convert-cosine-into-degrees?fbclid=IwAR0U6sSRByN_sV0EeQt0Q5I3HLOekxPiqe-iKv6eNjRBpuYjc8U68_IWZDg
// cos(x) = angle
// -> x =
let angle = (self.curveRadius - self.curveTop) / self.curveRadius
let angleRadian = acos(angle)
let engleToDegree = angleRadian * 180 / .pi
let startAngleDree = 180 + 90 - engleToDegree
let endAngleDree = 180 + 90 + engleToDegree
// cạnh đáy của tam giác cân ~ pitago
let bc = pow(self.curveRadius, 2)
let hc = bc - pow(self.curveRadius - self.curveTop, 2)
let ac = sqrt(hc)
let path = UIBezierPath()
let centerWidth = self.frame.width / 2
path.move(to: .zero)
path.addLine(to: .init(x: centerWidth - ac, y: 0))
path.move(to: .init(x: centerWidth - ac, y: 0))
path.addArc(withCenter: self.getCenter(), radius: self.curveRadius, startAngle: .pi * startAngleDree / 180.0, endAngle: .pi * endAngleDree / 180, clockwise: true)
path.move(to: .init(x: centerWidth + ac, y: 0))
path.addLine(to: CGPoint.init(x: self.frame.width, y: 0))
path.close()
return path.cgPath
}
private func getCenter() -> CGPoint {
return CGPoint.init(x: self.frame.width / 2, y: (self.frame.height * self.getAlpha() - self.getSafeBottom() ) / 2 )
}
private func getCenterCicle() -> CGPoint {
return CGPoint.init(x: self.frame.width / 2, y: (self.frame.height * self.getAlpha() - self.getSafeBottom() ) / 2 )
}
//
private func addYellowCicle() {
let shape = CAShapeLayer()
shape.fillColor = UIColor.red.cgColor
shape.path = UIBezierPath.init(arcCenter: self.getCenterCicle(), radius: self.getCircleYellowRadius(), startAngle: 0, endAngle: .pi * 2, clockwise: true).cgPath
if let s = self.circleLayer {
self.layer.replaceSublayer(s, with: shape)
} else {
self.layer.insertSublayer(shape, at: 1)
}
self.circleLayer = shape
}
private func getSafeBottom() -> CGFloat {
if #available(iOS 11.0, *) {
return self.safeAreaInsets.bottom
} else {
return 0
}
}
}
extension HomeTabBar {
override var traitCollection: UITraitCollection {
return UITraitCollection.init(horizontalSizeClass: .unspecified)
}
override func layoutSubviews() {
super.layoutSubviews()
self.itemPositioning = .centered
}
override open func sizeThatFits(_ size: CGSize) -> CGSize {
var sizeThatFits = super.sizeThatFits(size)
if #available(iOS 11.0, *) {
sizeThatFits.height = 74 + safeAreaInsets.bottom / 2
}
else {
sizeThatFits.height = 74
}
return sizeThatFits
}
}
extension UITabBar {
func setupCenterTabbarItem() {
if let items = self.items {
let height = self.bounds.height
let numItems = CGFloat(items.count)
let itemSize = CGSize(width: self.frame.width / numItems,
height: self.frame.height)
for (index, _) in items.enumerated() {
if index == 2 {
//Xposition of the item
let xPosition = itemSize.width * CGFloat(index)
let centerView = createSeparatorView(frame: CGRect.init(x: xPosition, y: 0, width: ViewService.screenSize().width/5, height: height), true)
centerView.backgroundColor = .clear
self.insertSubview(centerView, at: 1)
}
}
}
}
func insertSeparatorLineView() {
if let items = self.items {
//Get the height of the tab bar
let height = self.bounds.height
//Calculate the size of the items
let numItems = CGFloat(items.count)
let itemSize = CGSize(width: self.frame.width / numItems,
height: self.frame.height)
for (index, _) in items.enumerated() {
if index == 1 || index == 4 {
//Xposition of the item
let xPosition = itemSize.width * CGFloat(index)
let separator = UIView(frame: CGRect(x: xPosition, y: 0, width: 0.5, height: height))
let separator1 = createSeparatorView(frame: CGRect.init(x: xPosition, y: 0, width: 0.5, height: height))
separator.backgroundColor = .clear
self.insertSubview(separator1, at: 1)
}
}
}
}
func createSeparatorView(frame: CGRect,_ isCenter: Bool = false) -> UIView {
let wrapperView: UIView = UIView.init(frame: frame)
let lineView: UIView = UIView()
let height = self.bounds.height
wrapperView.backgroundColor = .clear
wrapperView.addSubviewForLayout(lineView)
if isCenter {
lineView.backgroundColor = .clear
wrapperView.addConstraints([
lineView.alignTop(to: wrapperView,space: -15),
lineView.alignLeading(to: wrapperView),
lineView.alignTrailing(to: wrapperView),
lineView.alignBottom(to: wrapperView)
])
let imageView = UIImageView()
imageView.image = IconSystem.make(.home)
imageView.tintColor = .white
lineView.addSubviewForLayout(imageView)
// wrapperView.addConstraints([
// imageView.relationCenterX(to: wrapperView),
// imageView.relationCenterY(to: wrapperView)])
lineView.addConstraints([imageView.relationCenterX(to: lineView), imageView.spacingBottom(to: lineView, space: height - 20)])
}
else {
lineView.backgroundColor = UIColor.init(0xD8D8D8)
if #available(iOS 11.0, *) {
wrapperView.addConstraints([
lineView.alignTop(to: wrapperView, space: 15 ), // safeAreaInsets.bottom / 4
lineView.alignLeading(to: wrapperView),
lineView.alignTrailing(to: wrapperView),
lineView.alignBottom(to: wrapperView, space: 15) // self.safeAreaInsets.bottom
])
} else {
wrapperView.addConstraints([
lineView.alignTop(to: wrapperView, space: 15),
lineView.alignLeading(to: wrapperView),
lineView.alignTrailing(to: wrapperView),
lineView.alignBottom(to: wrapperView, space: 15)
])
}
}
lineView.addConstraints([lineView.configWidth(0.5), lineView.configHeight(height)])
return wrapperView
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment