Visual_Novel_iOS/crush/Crush/Src/Modules/Tab/View/TabBar.swift

279 lines
7.9 KiB
Swift
Executable File

//
// TabBar.swift
// Tabbar
//
// Created by lym on 2021/1/1.
//
import Lottie
import UIKit
protocol TabBarDelegate: AnyObject {
func tabBar(_ tabBar: TabBar, didSelectItemAt index: TabBarItemIndex)
func tabBar(_ tabBar: TabBar, canTapEnterItem index: TabBarItemIndex) -> Bool
}
class TabBar: UITabBar {
weak var tabBarDelegate: TabBarDelegate?
var tabItems: [TabbarItem]? {
didSet {
guard let items = tabItems else {
return
}
containerStack.removeSubviews()
for (index, item) in items.enumerated() {
containerStack.addArrangedSubview(item)
item.addTarget(self, action: #selector(clickItem), for: .touchUpInside)
item.selectedStatus = index == 0
}
}
}
static let containerHeight: CGFloat = 52
private var containerInsets = UIEdgeInsets(top: 20, left: 24, bottom: 24, right: 24)
private var container: UIView = {
let view = UIView()
view.backgroundColor = .clear // clear
return view
}()
private var containerStack: UIStackView = {
let stack = UIStackView()
stack.axis = .horizontal
stack.distribution = .fillEqually
stack.spacing = 0
return stack
}()
private lazy var bgView: UIView = {
let view = UIView()
view.backgroundColor = .c.csdn
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
if #available(iOS 13.0, *) {
let appearance = self.standardAppearance.copy()
appearance.backgroundImage = UIColor.clear.toImage() ?? UIImage()
appearance.shadowImage = UIColor.clear.toImage() ?? UIImage()
appearance.shadowColor = .clear
appearance.configureWithTransparentBackground()
self.standardAppearance = appearance
} else {
backgroundImage = UIColor.clear.toImage() ?? UIImage()
shadowImage = UIColor.clear.toImage() ?? UIImage()
isTranslucent = true
barTintColor = .clear
}
backgroundColor = .c.cbd
addSubview(bgView)
bgView.addSubview(container)
container.layer.cornerRadius = TabBar.containerHeight / 2
container.addSubview(containerStack)
bringSubviewToFront(bgView)
bgView.snp.makeConstraints { make in
make.edges.equalToSuperview().inset(UIEdgeInsets.zero)
}
let bottom = safeAreaInsets.bottom > 0 ? safeAreaInsets.bottom : containerInsets.bottom
container.snp.makeConstraints { make in
make.left.equalToSuperview().offset(16)//(containerInsets.left)
make.right.equalToSuperview().offset(-16)//(-containerInsets.right)
make.height.equalTo(TabBar.containerHeight)
make.bottom.equalToSuperview().offset(-bottom)
make.bottom.equalToSuperview()
}
containerStack.snp.makeConstraints { make in
make.edges.equalToSuperview().inset(UIEdgeInsets.zero)
}
}
@available(*, unavailable)
required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if clipsToBounds || alpha == 0 || isHidden {
return nil
}
for item in containerStack.arrangedSubviews.reversed() {
let subPoint = item.convert(point, from: self)
let imgPoint = (item as! TitleItem).imageView.convert(point, from: self)
let flag = item.point(inside: subPoint, with: event)
let flag2 = item.point(inside: imgPoint, with: event)
if flag || flag2 {
return item
}
}
return super.hitTest(point, with: event)
}
// override func layoutSubviews() {
// super.layoutSubviews()
// }
}
extension TabBar {
public func setSelected(selected _: Bool, index: TabBarItemIndex) {
guard let items = tabItems else { return }
items.forEach { item in
if item.itemIndex == index {
item.selectedStatus = true
item.starAnimation()
} else {
item.selectedStatus = false
item.stopAnimation()
}
}
}
public func setCount(count: Int, index: TabBarItemIndex) {
guard let items = tabItems else { return }
items.forEach { item in
if item.itemIndex == index {
item.count = count
}
}
}
}
extension TabBar {
@objc private func clickItem(_ sender: TitleItem) {
switch sender.itemIndex {
case .friend, .me, .discover, .home, .add:
if let can = tabBarDelegate?.tabBar(self, canTapEnterItem: sender.itemIndex), can == true {
setSelected(selected: true, index: sender.itemIndex)
tabBarDelegate?.tabBar(self, didSelectItemAt: sender.itemIndex)
}
// case .add:
// tabBarDelegate?.tabBar(self, didSelectItemAt: sender.itemIndex)
// }
}
}
}
// MARK: - TabBar item
enum TabBarItemIndex {
case home
case friend
///
case add
case discover
case me
}
enum TitleItemStyle {
case small
case large
}
protocol TabbarItem: UIControl {
var selectedStatus: Bool { get set }
var count: Int { get set }
var itemIndex: TabBarItemIndex { get set }
func starAnimation()
func stopAnimation()
}
extension TabbarItem {
func starAnimation() {}
func stopAnimation() {}
}
class TitleItem: UIControl, TabbarItem {
private var titleLabel: UILabel!
//private var bage: PaddingLabel!
private var badgeView: BadgeView!
// private var lotiView: AnimationView!
var imageView: UIImageView!
var image: UIImage!
var selectedImage: UIImage!
var style: TitleItemStyle!
var font = UIFont.t.tll // UIFont = .popSemiBold(size: 12)
var selectedFont: UIFont = .t.tll // .popSemiBold(size: 12)
var textColor: UIColor = .c.ctsn
var selectedTextColor: UIColor = .white // .hexEF7000
public var title: String {
didSet {
titleLabel.text = title
}
}
public var count: Int = 0 {
didSet {
badgeView.isHidden = count <= 0
badgeView.badgeValue = count// > 99 ? "99+" : "\(count)"
}
}
public var selectedStatus: Bool = false {
didSet {
if selectedStatus {
imageView.image = selectedImage
} else {
imageView.image = image
}
}
}
public var itemIndex: TabBarItemIndex
init(title: String, image: UIImage,
selectedImage: UIImage,
count: Int = 0,
style: TitleItemStyle = .small,
itemIndex: TabBarItemIndex) {
self.title = title
self.count = count
self.image = image
self.selectedImage = selectedImage
self.style = style
self.itemIndex = itemIndex
super.init(frame: CGRect.zero)
setUpUI()
}
@available(*, unavailable)
required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setUpUI() {
backgroundColor = .clear
imageView = UIImageView()
imageView.image = image
imageView.contentMode = .scaleAspectFit
addSubview(imageView)
imageView.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.centerY.equalToSuperview()
}
badgeView = {
let v = BadgeView()
v.showMax99 = true
addSubview(v)
v.snp.makeConstraints { make in
make.leading.equalTo(imageView.snp.trailing).offset(-8)
make.top.equalTo(imageView).offset(-4)
}
return v
}()
}
}