
问题: - refreshTabBar(isLogin:) 和 refreshTabBarWithIsLogin(_:) - 在 OC 中生成相同的 selector 'refreshTabBarWithIsLogin:' - 导致编译冲突 修复: - 移除 refreshTabBar(isLogin:) 的 @objc 标记 - 保留 refreshTabBarWithIsLogin(_:) 的 @objc 标记 - 内部调用改为 Swift 方法 这样 OC 只能看到 refreshTabBarWithIsLogin: 方法 Swift 内部可以使用更简洁的 refreshTabBar(isLogin:) 方法
320 lines
11 KiB
Swift
320 lines
11 KiB
Swift
//
|
||
// EPTabBarController.swift
|
||
// YuMi
|
||
//
|
||
// Created by AI on 2025-10-09.
|
||
// Copyright © 2025 YuMi. All rights reserved.
|
||
//
|
||
|
||
import UIKit
|
||
|
||
/// EP 系列 TabBar 控制器
|
||
/// 悬浮设计 + 液态玻璃效果,只包含 Moment 和 Mine 两个 Tab
|
||
@objc class EPTabBarController: UITabBarController {
|
||
|
||
// MARK: - Properties
|
||
|
||
/// 全局事件管理器
|
||
private var globalEventManager: GlobalEventManager?
|
||
|
||
/// 是否已登录
|
||
private var isLoggedIn: Bool = false
|
||
|
||
/// 自定义悬浮 TabBar 容器
|
||
private var customTabBarView: UIView!
|
||
|
||
/// 毛玻璃背景视图
|
||
private var tabBarBackgroundView: UIVisualEffectView!
|
||
|
||
/// Tab 按钮数组
|
||
private var tabButtons: [UIButton] = []
|
||
|
||
// MARK: - Lifecycle
|
||
|
||
override func viewDidLoad() {
|
||
super.viewDidLoad()
|
||
|
||
// 测试域名配置
|
||
#if DEBUG
|
||
APIConfig.testEncryption()
|
||
#endif
|
||
|
||
// 隐藏原生 TabBar
|
||
self.tabBar.isHidden = true
|
||
|
||
setupCustomFloatingTabBar()
|
||
setupGlobalManagers()
|
||
setupInitialViewControllers()
|
||
|
||
NSLog("[EPTabBarController] 悬浮 TabBar 初始化完成")
|
||
}
|
||
|
||
deinit {
|
||
globalEventManager?.removeAllDelegates()
|
||
NSLog("[EPTabBarController] 已释放")
|
||
}
|
||
|
||
// MARK: - Setup
|
||
|
||
/// 设置自定义悬浮 TabBar
|
||
private func setupCustomFloatingTabBar() {
|
||
// 创建悬浮容器
|
||
customTabBarView = UIView()
|
||
customTabBarView.translatesAutoresizingMaskIntoConstraints = false
|
||
customTabBarView.backgroundColor = .clear
|
||
view.addSubview(customTabBarView)
|
||
|
||
// 液态玻璃/毛玻璃效果
|
||
let blurEffect: UIBlurEffect
|
||
if #available(iOS 18.0, *) {
|
||
// iOS 18+ 使用液态玻璃(Material)
|
||
blurEffect = UIBlurEffect(style: .systemChromeMaterial)
|
||
} else {
|
||
// iOS 13-17 使用毛玻璃
|
||
blurEffect = UIBlurEffect(style: .systemThinMaterial)
|
||
}
|
||
|
||
tabBarBackgroundView = UIVisualEffectView(effect: blurEffect)
|
||
tabBarBackgroundView.translatesAutoresizingMaskIntoConstraints = false
|
||
tabBarBackgroundView.layer.cornerRadius = 28
|
||
tabBarBackgroundView.layer.masksToBounds = true
|
||
|
||
// 添加边框
|
||
tabBarBackgroundView.layer.borderWidth = 0.5
|
||
tabBarBackgroundView.layer.borderColor = UIColor.white.withAlphaComponent(0.2).cgColor
|
||
|
||
customTabBarView.addSubview(tabBarBackgroundView)
|
||
|
||
// 添加阴影
|
||
customTabBarView.layer.shadowColor = UIColor.black.cgColor
|
||
customTabBarView.layer.shadowOpacity = 0.15
|
||
customTabBarView.layer.shadowOffset = CGSize(width: 0, height: -2)
|
||
customTabBarView.layer.shadowRadius = 10
|
||
customTabBarView.layer.shadowPath = nil // 自动计算
|
||
|
||
// 布局约束(悬浮,两侧留白 16pt,底部留白 12pt)
|
||
NSLayoutConstraint.activate([
|
||
// TabBar 容器
|
||
customTabBarView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
|
||
customTabBarView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
|
||
customTabBarView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -12),
|
||
customTabBarView.heightAnchor.constraint(equalToConstant: 64),
|
||
|
||
// 背景视图
|
||
tabBarBackgroundView.topAnchor.constraint(equalTo: customTabBarView.topAnchor),
|
||
tabBarBackgroundView.leadingAnchor.constraint(equalTo: customTabBarView.leadingAnchor),
|
||
tabBarBackgroundView.trailingAnchor.constraint(equalTo: customTabBarView.trailingAnchor),
|
||
tabBarBackgroundView.bottomAnchor.constraint(equalTo: customTabBarView.bottomAnchor)
|
||
])
|
||
|
||
// 添加 Tab 按钮
|
||
setupTabButtons()
|
||
|
||
NSLog("[EPTabBarController] 悬浮 TabBar 设置完成")
|
||
}
|
||
|
||
/// 设置 Tab 按钮
|
||
private func setupTabButtons() {
|
||
let momentButton = createTabButton(
|
||
icon: "sparkles", // 临时使用 SF Symbols
|
||
title: "动态",
|
||
tag: 0
|
||
)
|
||
|
||
let mineButton = createTabButton(
|
||
icon: "person.circle",
|
||
title: "我的",
|
||
tag: 1
|
||
)
|
||
|
||
tabButtons = [momentButton, mineButton]
|
||
|
||
let stackView = UIStackView(arrangedSubviews: tabButtons)
|
||
stackView.axis = .horizontal
|
||
stackView.distribution = .fillEqually
|
||
stackView.spacing = 20
|
||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||
tabBarBackgroundView.contentView.addSubview(stackView)
|
||
|
||
NSLayoutConstraint.activate([
|
||
stackView.topAnchor.constraint(equalTo: tabBarBackgroundView.topAnchor, constant: 8),
|
||
stackView.leadingAnchor.constraint(equalTo: tabBarBackgroundView.leadingAnchor, constant: 20),
|
||
stackView.trailingAnchor.constraint(equalTo: tabBarBackgroundView.trailingAnchor, constant: -20),
|
||
stackView.bottomAnchor.constraint(equalTo: tabBarBackgroundView.bottomAnchor, constant: -8)
|
||
])
|
||
|
||
// 默认选中第一个
|
||
updateTabButtonStates(selectedIndex: 0)
|
||
}
|
||
|
||
/// 创建 Tab 按钮
|
||
private func createTabButton(icon: String, title: String, tag: Int) -> UIButton {
|
||
let button = UIButton(type: .custom)
|
||
button.tag = tag
|
||
|
||
// 设置图标
|
||
let imageConfig = UIImage.SymbolConfiguration(pointSize: 20, weight: .medium)
|
||
let iconImage = UIImage(systemName: icon, withConfiguration: imageConfig)
|
||
button.setImage(iconImage, for: .normal)
|
||
|
||
// 设置标题
|
||
button.setTitle(title, for: .normal)
|
||
button.titleLabel?.font = UIFont.systemFont(ofSize: 12, weight: .medium)
|
||
|
||
// 设置颜色
|
||
button.setTitleColor(.white.withAlphaComponent(0.6), for: .normal)
|
||
button.setTitleColor(.white, for: .selected)
|
||
button.tintColor = .white.withAlphaComponent(0.6)
|
||
|
||
// 设置布局
|
||
button.titleEdgeInsets = UIEdgeInsets(top: 25, left: -20, bottom: -25, right: 0)
|
||
button.imageEdgeInsets = UIEdgeInsets(top: -10, left: 0, bottom: 10, right: 0)
|
||
|
||
button.addTarget(self, action: #selector(tabButtonTapped(_:)), for: .touchUpInside)
|
||
return button
|
||
}
|
||
|
||
/// Tab 按钮点击事件
|
||
@objc private func tabButtonTapped(_ sender: UIButton) {
|
||
selectedIndex = sender.tag
|
||
updateTabButtonStates(selectedIndex: sender.tag)
|
||
|
||
let tabNames = ["动态", "我的"]
|
||
NSLog("[EPTabBarController] 选中 Tab: \(tabNames[sender.tag])")
|
||
}
|
||
|
||
/// 更新 Tab 按钮状态
|
||
private func updateTabButtonStates(selectedIndex: Int) {
|
||
for (index, button) in tabButtons.enumerated() {
|
||
let isSelected = (index == selectedIndex)
|
||
button.isSelected = isSelected
|
||
button.tintColor = isSelected ? .white : .white.withAlphaComponent(0.6)
|
||
button.setTitleColor(isSelected ? .white : .white.withAlphaComponent(0.6), for: .normal)
|
||
|
||
// 选中状态动画
|
||
UIView.animate(withDuration: 0.2) {
|
||
button.transform = isSelected ? CGAffineTransform(scaleX: 1.1, y: 1.1) : .identity
|
||
}
|
||
}
|
||
}
|
||
|
||
/// 设置全局管理器
|
||
private func setupGlobalManagers() {
|
||
globalEventManager = GlobalEventManager.shared()
|
||
globalEventManager?.setupSDKDelegates()
|
||
|
||
// 设置房间最小化视图
|
||
if let containerView = view {
|
||
globalEventManager?.setupRoomMiniView(on: containerView)
|
||
}
|
||
|
||
// 注册社交分享回调
|
||
globalEventManager?.registerSocialShareCallback()
|
||
|
||
NSLog("[EPTabBarController] 全局管理器设置完成")
|
||
}
|
||
|
||
/// 设置初始 ViewController(未登录状态)
|
||
private func setupInitialViewControllers() {
|
||
// TODO: 暂时使用空白页面占位
|
||
let blankVC1 = UIViewController()
|
||
blankVC1.view.backgroundColor = .white
|
||
blankVC1.tabBarItem = createTabBarItem(
|
||
title: "动态",
|
||
normalImage: "tab_moment_normal",
|
||
selectedImage: "tab_moment_selected"
|
||
)
|
||
|
||
let blankVC2 = UIViewController()
|
||
blankVC2.view.backgroundColor = .white
|
||
blankVC2.tabBarItem = createTabBarItem(
|
||
title: "我的",
|
||
normalImage: "tab_mine_normal",
|
||
selectedImage: "tab_mine_selected"
|
||
)
|
||
|
||
viewControllers = [blankVC1, blankVC2]
|
||
selectedIndex = 0
|
||
|
||
NSLog("[EPTabBarController] 初始 ViewControllers 设置完成")
|
||
}
|
||
|
||
/// 创建 TabBarItem
|
||
/// - Parameters:
|
||
/// - title: 标题
|
||
/// - normalImage: 未选中图标名称
|
||
/// - selectedImage: 选中图标名称
|
||
/// - Returns: UITabBarItem
|
||
private func createTabBarItem(title: String, normalImage: String, selectedImage: String) -> UITabBarItem {
|
||
let item = UITabBarItem(
|
||
title: title,
|
||
image: UIImage(named: normalImage)?.withRenderingMode(.alwaysOriginal),
|
||
selectedImage: UIImage(named: selectedImage)?.withRenderingMode(.alwaysOriginal)
|
||
)
|
||
return item
|
||
}
|
||
|
||
// MARK: - Public Methods
|
||
|
||
/// 登录成功后刷新 TabBar
|
||
/// - Parameter isLogin: 是否已登录
|
||
func refreshTabBar(isLogin: Bool) {
|
||
isLoggedIn = isLogin
|
||
|
||
if isLogin {
|
||
setupLoggedInViewControllers()
|
||
} else {
|
||
setupInitialViewControllers()
|
||
}
|
||
|
||
NSLog("[EPTabBarController] TabBar 已刷新,登录状态: \(isLogin)")
|
||
}
|
||
|
||
/// 设置登录后的 ViewControllers
|
||
private func setupLoggedInViewControllers() {
|
||
// 创建真实的 ViewController(OC 类)
|
||
let momentVC = EPMomentViewController()
|
||
momentVC.tabBarItem = createTabBarItem(
|
||
title: "动态",
|
||
normalImage: "tab_moment_normal",
|
||
selectedImage: "tab_moment_selected"
|
||
)
|
||
|
||
let mineVC = EPMineViewController()
|
||
mineVC.tabBarItem = createTabBarItem(
|
||
title: "我的",
|
||
normalImage: "tab_mine_normal",
|
||
selectedImage: "tab_mine_selected"
|
||
)
|
||
|
||
viewControllers = [momentVC, mineVC]
|
||
selectedIndex = 0
|
||
|
||
NSLog("[EPTabBarController] 登录后 ViewControllers 设置完成 - Moment & Mine")
|
||
}
|
||
}
|
||
|
||
// MARK: - UITabBarControllerDelegate
|
||
|
||
extension EPTabBarController: UITabBarControllerDelegate {
|
||
|
||
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
|
||
NSLog("[EPTabBarController] 选中 Tab: \(item.title ?? "Unknown")")
|
||
}
|
||
}
|
||
|
||
// MARK: - OC Compatibility
|
||
|
||
extension EPTabBarController {
|
||
|
||
/// OC 兼容:创建实例的工厂方法
|
||
@objc static func create() -> EPTabBarController {
|
||
return EPTabBarController()
|
||
}
|
||
|
||
/// OC 兼容:刷新 TabBar 方法
|
||
@objc func refreshTabBarWithIsLogin(_ isLogin: Bool) {
|
||
refreshTabBar(isLogin: isLogin)
|
||
}
|
||
}
|