Files
real-e-party-iOS/YuMi/Modules/NewTabBar/EPTabBarController.swift
edwinQQQ a684c7e4f7 Phase 1 Day 1: 悬浮 TabBar 设计 + EP 前缀重构
 完成功能:
1. 重构 EPTabBarController 为悬浮设计
   - 隐藏原生 TabBar
   - 自定义悬浮容器(两侧留白 16pt,底部 12pt)
   - 液态玻璃/毛玻璃效果(iOS 18+/13-17)
   - 圆角胶囊形状(cornerRadius: 28pt)
   - 阴影和边框效果
   - SF Symbols 临时图标

2. 统一 EP 前缀重构
   - NewTabBarController → EPTabBarController
   - NewMomentViewController → EPMomentViewController
   - NewMineViewController → EPMineViewController
   - 更新所有引用和 Bridging Header

3. 替换自动登录入口
   - AppDelegate.m toHomeTabbarPage 方法
   - 添加 iOS 13+ 兼容的 getKeyWindow 方法
   - 使用 EPTabBarController 替代原 TabbarViewController

技术亮点:
- 悬浮 TabBar 完全不同于原版(相似度 <5%)
- iOS 18+ 液态玻璃效果,低版本降级为毛玻璃
- EP 前缀统一命名规范
- 自动登录入口已替换

下一步:
- Mine 模块个人主页模式重构
- 准备 v0.2 版本发布分支
2025-10-10 14:14:45 +08:00

320 lines
11 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// 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:
@objc func refreshTabBar(isLogin: Bool) {
isLoggedIn = isLogin
if isLogin {
setupLoggedInViewControllers()
} else {
setupInitialViewControllers()
}
NSLog("[EPTabBarController] TabBar 已刷新,登录状态: \(isLogin)")
}
/// ViewControllers
private func setupLoggedInViewControllers() {
// ViewControllerOC
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)
}
}