// // EPTabBarController.swift // YuMi // // Created by AI on 2025-10-09. // Copyright © 2025 YuMi. All rights reserved. // import UIKit import SnapKit /// 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 effect: UIVisualEffect if #available(iOS 26.0, *) { // iOS 26+ 使用液态玻璃(Material) effect = UIGlassEffect() } else { // iOS 13-17 使用毛玻璃 effect = UIBlurEffect(style: .systemUltraThinMaterial) } tabBarBackgroundView = UIVisualEffectView(effect: effect) 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 // 自动计算 // 简化的布局约束(类似 Masonry 风格) customTabBarView.snp.makeConstraints { make in make.leading.equalTo(view).offset(16) make.trailing.equalTo(view).offset(-16) make.bottom.equalTo(view.safeAreaLayoutGuide).offset(-12) make.height.equalTo(64) } tabBarBackgroundView.snp.makeConstraints { make in make.edges.equalTo(customTabBarView) } // 添加 Tab 按钮 setupTabButtons() NSLog("[EPTabBarController] 悬浮 TabBar 设置完成") } /// 设置 Tab 按钮 private func setupTabButtons() { let momentButton = createTabButton( normalImage: "tab_moment_off", selectedImage: "tab_moment_on", tag: 0 ) let mineButton = createTabButton( normalImage: "tab_mine_off", selectedImage: "tab_mine_on", 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) stackView.snp.makeConstraints { make in make.top.equalTo(tabBarBackgroundView).offset(8) make.leading.equalTo(tabBarBackgroundView).offset(20) make.trailing.equalTo(tabBarBackgroundView).offset(-20) make.bottom.equalTo(tabBarBackgroundView).offset(-8) } // 默认选中第一个 updateTabButtonStates(selectedIndex: 0) } /// 创建 Tab 按钮 private func createTabButton(normalImage: String, selectedImage: String, tag: Int) -> UIButton { let button = UIButton(type: .custom) button.tag = tag // 尝试设置自定义图片,如果不存在则使用 SF Symbols if let normalImg = UIImage(named: normalImage), let selectedImg = UIImage(named: selectedImage) { // 使用自定义图片 button.setImage(normalImg, for: .normal) button.setImage(selectedImg, for: .selected) } else { // 使用 SF Symbols 作为备用 let fallbackIcons = ["sparkles", "person.circle"] let iconName = fallbackIcons[tag] let imageConfig = UIImage.SymbolConfiguration(pointSize: 24, weight: .medium) button.setImage(UIImage(systemName: iconName, withConfiguration: imageConfig), for: .normal) button.setImage(UIImage(systemName: iconName, withConfiguration: imageConfig), for: .selected) button.tintColor = .white.withAlphaComponent(0.6) } // 图片渲染模式 button.imageView?.contentMode = .scaleAspectFit // 移除标题,只使用图片 button.setTitle(nil, for: .normal) button.setTitle(nil, for: .selected) // 设置图片大小约束 button.imageView?.snp.makeConstraints { make in make.size.equalTo(28) // 图标大小 } 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 // 如果是 SF Symbols,更新 tintColor if button.tintColor != nil { button.tintColor = isSelected ? .white : .white.withAlphaComponent(0.6) } // 选中状态动画 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) } }