Created
July 4, 2020 15:50
-
-
Save phuongddx/ff3771bcee4caf4dc31fd23d40a94da1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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