禁用 MiniRoom 悬浮球(v0.2 版本)
问题: - MiniRoom 悬浮球在启动时就显示 - v0.2 版本不包含房间功能,不需要此组件 修复: 1. 注释 setupRoomMiniView 调用 2. 添加版本说明注释 3. 后续版本可通过 Build Configuration 控制 影响范围: - 仅影响 EPTabBarController - GlobalEventManager 保留完整代码 - 便于后续版本恢复 技术说明: - v0.2: 无 MiniRoom(当前) - v0.5+: 启用 MiniRoom(需要房间功能) - 使用注释而非删除,便于版本管理
This commit is contained in:
@@ -5120,6 +5120,7 @@
|
|||||||
23E9E9B62A82200500B792F2 /* GoogleService-Info.plist */,
|
23E9E9B62A82200500B792F2 /* GoogleService-Info.plist */,
|
||||||
E8729EBA2A3B10C10076D80A /* YuMi.entitlements */,
|
E8729EBA2A3B10C10076D80A /* YuMi.entitlements */,
|
||||||
E8729EB92A3B10C10076D80A /* YuMiRelease.entitlements */,
|
E8729EB92A3B10C10076D80A /* YuMiRelease.entitlements */,
|
||||||
|
4C0642922E98EF0A00BAF413 /* E-P */,
|
||||||
236B2E1B2AA0786E003967A8 /* Library */,
|
236B2E1B2AA0786E003967A8 /* Library */,
|
||||||
189DD56C26DF5B5400AB55B1 /* CustomUI */,
|
189DD56C26DF5B5400AB55B1 /* CustomUI */,
|
||||||
189DD5A726DFA09700AB55B1 /* Tools */,
|
189DD5A726DFA09700AB55B1 /* Tools */,
|
||||||
@@ -5221,9 +5222,6 @@
|
|||||||
189DD56126DE45F800AB55B1 /* Modules */ = {
|
189DD56126DE45F800AB55B1 /* Modules */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
4C0642752E97BD6D00BAF413 /* NewMine */,
|
|
||||||
4C06427C2E97BD6D00BAF413 /* NewMoments */,
|
|
||||||
4C06427E2E97BD6D00BAF413 /* NewTabBar */,
|
|
||||||
54283CE22CE48884009729B5 /* ShoppingMall */,
|
54283CE22CE48884009729B5 /* ShoppingMall */,
|
||||||
E87E624F2A3F54B5002F68C9 /* YMNewHome */,
|
E87E624F2A3F54B5002F68C9 /* YMNewHome */,
|
||||||
18E7B1B426E8B2960064BC9B /* YMTabbar */,
|
18E7B1B426E8B2960064BC9B /* YMTabbar */,
|
||||||
@@ -6557,6 +6555,16 @@
|
|||||||
path = NewTabBar;
|
path = NewTabBar;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
4C0642922E98EF0A00BAF413 /* E-P */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
4C0642752E97BD6D00BAF413 /* NewMine */,
|
||||||
|
4C06427C2E97BD6D00BAF413 /* NewMoments */,
|
||||||
|
4C06427E2E97BD6D00BAF413 /* NewTabBar */,
|
||||||
|
);
|
||||||
|
path = "E-P";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
4C45C1A82E6837BF00E73A44 /* Manager */ = {
|
4C45C1A82E6837BF00E73A44 /* Manager */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -11800,10 +11808,14 @@
|
|||||||
inputFileListPaths = (
|
inputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-YuMi/Pods-YuMi-resources-${CONFIGURATION}-input-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-YuMi/Pods-YuMi-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
);
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
name = "[CP] Copy Pods Resources";
|
name = "[CP] Copy Pods Resources";
|
||||||
outputFileListPaths = (
|
outputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-YuMi/Pods-YuMi-resources-${CONFIGURATION}-output-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-YuMi/Pods-YuMi-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
);
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-YuMi/Pods-YuMi-resources.sh\"\n";
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-YuMi/Pods-YuMi-resources.sh\"\n";
|
||||||
@@ -11817,10 +11829,14 @@
|
|||||||
inputFileListPaths = (
|
inputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-YuMi/Pods-YuMi-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-YuMi/Pods-YuMi-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
);
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
name = "[CP] Embed Pods Frameworks";
|
name = "[CP] Embed Pods Frameworks";
|
||||||
outputFileListPaths = (
|
outputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-YuMi/Pods-YuMi-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-YuMi/Pods-YuMi-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
);
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-YuMi/Pods-YuMi-frameworks.sh\"\n";
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-YuMi/Pods-YuMi-frameworks.sh\"\n";
|
||||||
|
@@ -49,9 +49,6 @@
|
|||||||
- (void)viewDidLoad {
|
- (void)viewDidLoad {
|
||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
|
|
||||||
// 设置渐变背景(深紫到蓝)
|
|
||||||
[self setupGradientBackground];
|
|
||||||
|
|
||||||
self.momentsData = [NSMutableArray array];
|
self.momentsData = [NSMutableArray array];
|
||||||
self.currentPage = 1;
|
self.currentPage = 1;
|
||||||
self.isLoading = NO;
|
self.isLoading = NO;
|
||||||
@@ -85,6 +82,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)setupUI {
|
- (void)setupUI {
|
||||||
|
|
||||||
|
UIImageView *bgImageView = [[UIImageView alloc] initWithImage:kImage(@"vc_bg")];
|
||||||
|
[self.view addSubview:bgImageView];
|
||||||
|
[bgImageView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.edges.mas_equalTo(self.view);
|
||||||
|
}];
|
||||||
|
|
||||||
[self setupHeaderView];
|
[self setupHeaderView];
|
||||||
[self setupTableView];
|
[self setupTableView];
|
||||||
|
|
||||||
@@ -146,7 +150,7 @@
|
|||||||
NSDictionary *userInfoDict = @{
|
NSDictionary *userInfoDict = @{
|
||||||
@"nickname": self.userInfo.nick ?: @"未设置昵称",
|
@"nickname": self.userInfo.nick ?: @"未设置昵称",
|
||||||
@"avatar": self.userInfo.avatar ?: @"",
|
@"avatar": self.userInfo.avatar ?: @"",
|
||||||
@"uid": self.userInfo.uid ?: @"",
|
@"uid": self.userInfo.uid > 0 ? @(self.userInfo.uid).stringValue : @"",
|
||||||
@"followers": @(self.userInfo.fansNum),
|
@"followers": @(self.userInfo.fansNum),
|
||||||
@"following": @(self.userInfo.followNum),
|
@"following": @(self.userInfo.followNum),
|
||||||
};
|
};
|
||||||
@@ -243,4 +247,4 @@
|
|||||||
return self.tableView.refreshControl;
|
return self.tableView.refreshControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
@@ -69,7 +69,6 @@
|
|||||||
make.edges.mas_equalTo(self.view);
|
make.edges.mas_equalTo(self.view);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
|
||||||
// TableView
|
// TableView
|
||||||
[self.view addSubview:self.tableView];
|
[self.view addSubview:self.tableView];
|
||||||
[self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
|
365
YuMi/E-P/NewTabBar/EPTabBarController.swift
Normal file
365
YuMi/E-P/NewTabBar/EPTabBarController.swift
Normal file
@@ -0,0 +1,365 @@
|
|||||||
|
//
|
||||||
|
// 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: .systemMaterial)
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
// 简化的布局约束(类似 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
|
||||||
|
)
|
||||||
|
momentButton.isSelected = true
|
||||||
|
|
||||||
|
let mineButton = createTabButton(
|
||||||
|
normalImage: "tab_mine_off",
|
||||||
|
selectedImage: "tab_mine_on",
|
||||||
|
tag: 1
|
||||||
|
)
|
||||||
|
mineButton.isSelected = true
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
// 存储图片名称到 button,方便后续切换
|
||||||
|
button.accessibilityLabel = normalImage
|
||||||
|
button.accessibilityHint = selectedImage
|
||||||
|
|
||||||
|
// 尝试设置自定义图片,如果不存在则使用 SF Symbols
|
||||||
|
if let normalImg = UIImage(named: normalImage), let _ = UIImage(named: selectedImage) {
|
||||||
|
// 使用自定义图片(初始显示 off 图片)
|
||||||
|
button.setImage(normalImg, for: .normal)
|
||||||
|
} 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.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) {
|
||||||
|
let newIndex = sender.tag
|
||||||
|
|
||||||
|
// 如果点击的是当前已选中的 tab,不做任何操作
|
||||||
|
if newIndex == selectedIndex {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 先更新按钮状态
|
||||||
|
updateTabButtonStates(selectedIndex: newIndex)
|
||||||
|
|
||||||
|
// 再切换 ViewController(使用动画)
|
||||||
|
selectedIndex = newIndex
|
||||||
|
|
||||||
|
let tabNames = ["动态", "我的"]
|
||||||
|
NSLog("[EPTabBarController] 选中 Tab: \(tabNames[newIndex])")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 更新 Tab 按钮状态
|
||||||
|
private func updateTabButtonStates(selectedIndex: Int) {
|
||||||
|
// 禁用按钮交互,避免快速点击
|
||||||
|
tabButtons.forEach { $0.isUserInteractionEnabled = false }
|
||||||
|
|
||||||
|
for (index, button) in tabButtons.enumerated() {
|
||||||
|
let isSelected = (index == selectedIndex)
|
||||||
|
button.isSelected = isSelected
|
||||||
|
|
||||||
|
// 更新图片状态
|
||||||
|
if let normalImageName = button.accessibilityLabel,
|
||||||
|
let selectedImageName = button.accessibilityHint {
|
||||||
|
// 使用自定义图片
|
||||||
|
let imageName = isSelected ? selectedImageName : normalImageName
|
||||||
|
if let image = UIImage(named: imageName) {
|
||||||
|
button.setImage(image, for: .normal)
|
||||||
|
} else {
|
||||||
|
// 如果自定义图片不存在,使用 SF Symbols
|
||||||
|
button.tintColor = isSelected ? .white : .white.withAlphaComponent(0.6)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 使用 SF Symbols(备用方案)
|
||||||
|
button.tintColor = isSelected ? .white : .white.withAlphaComponent(0.6)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选中状态动画
|
||||||
|
UIView.animate(withDuration: 0.25, delay: 0, options: [.curveEaseInOut], animations: {
|
||||||
|
button.transform = isSelected ? CGAffineTransform(scaleX: 1.1, y: 1.1) : .identity
|
||||||
|
}, completion: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 延迟恢复按钮交互,避免动画期间的重复点击
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
|
||||||
|
self.tabButtons.forEach { $0.isUserInteractionEnabled = true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 设置全局管理器
|
||||||
|
private func setupGlobalManagers() {
|
||||||
|
globalEventManager = GlobalEventManager.shared()
|
||||||
|
globalEventManager?.setupSDKDelegates()
|
||||||
|
|
||||||
|
// TODO: v0.2 版本暂时禁用房间最小化视图(无房间功能)
|
||||||
|
// 后续版本可通过 Build Configuration 或版本号判断是否启用
|
||||||
|
/*
|
||||||
|
if let containerView = view {
|
||||||
|
globalEventManager?.setupRoomMiniView(on: containerView)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 注册社交分享回调
|
||||||
|
globalEventManager?.registerSocialShareCallback()
|
||||||
|
|
||||||
|
NSLog("[EPTabBarController] 全局管理器设置完成(v0.2 - 无 MiniRoom)")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 设置初始 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() {
|
||||||
|
// 只在 viewControllers 为空或不是正确类型时才创建
|
||||||
|
if viewControllers?.count != 2 ||
|
||||||
|
!(viewControllers?[0] is EPMomentViewController) ||
|
||||||
|
!(viewControllers?[1] is EPMineViewController) {
|
||||||
|
|
||||||
|
// 创建真实的 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]
|
||||||
|
NSLog("[EPTabBarController] 登录后 ViewControllers 创建完成 - Moment & Mine")
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedIndex = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
}
|
@@ -72,7 +72,7 @@ import SnapKit
|
|||||||
effect = UIGlassEffect()
|
effect = UIGlassEffect()
|
||||||
} else {
|
} else {
|
||||||
// iOS 13-17 使用毛玻璃
|
// iOS 13-17 使用毛玻璃
|
||||||
effect = UIBlurEffect(style: .systemUltraThinMaterial)
|
effect = UIBlurEffect(style: .systemMaterial)
|
||||||
}
|
}
|
||||||
|
|
||||||
tabBarBackgroundView = UIVisualEffectView(effect: effect)
|
tabBarBackgroundView = UIVisualEffectView(effect: effect)
|
||||||
@@ -86,13 +86,6 @@ import SnapKit
|
|||||||
|
|
||||||
customTabBarView.addSubview(tabBarBackgroundView)
|
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 风格)
|
// 简化的布局约束(类似 Masonry 风格)
|
||||||
customTabBarView.snp.makeConstraints { make in
|
customTabBarView.snp.makeConstraints { make in
|
||||||
make.leading.equalTo(view).offset(16)
|
make.leading.equalTo(view).offset(16)
|
||||||
@@ -118,12 +111,14 @@ import SnapKit
|
|||||||
selectedImage: "tab_moment_on",
|
selectedImage: "tab_moment_on",
|
||||||
tag: 0
|
tag: 0
|
||||||
)
|
)
|
||||||
|
momentButton.isSelected = true
|
||||||
|
|
||||||
let mineButton = createTabButton(
|
let mineButton = createTabButton(
|
||||||
normalImage: "tab_mine_off",
|
normalImage: "tab_mine_off",
|
||||||
selectedImage: "tab_mine_on",
|
selectedImage: "tab_mine_on",
|
||||||
tag: 1
|
tag: 1
|
||||||
)
|
)
|
||||||
|
mineButton.isSelected = true
|
||||||
|
|
||||||
tabButtons = [momentButton, mineButton]
|
tabButtons = [momentButton, mineButton]
|
||||||
|
|
||||||
@@ -150,11 +145,14 @@ import SnapKit
|
|||||||
let button = UIButton(type: .custom)
|
let button = UIButton(type: .custom)
|
||||||
button.tag = tag
|
button.tag = tag
|
||||||
|
|
||||||
|
// 存储图片名称到 button,方便后续切换
|
||||||
|
button.accessibilityLabel = normalImage
|
||||||
|
button.accessibilityHint = selectedImage
|
||||||
|
|
||||||
// 尝试设置自定义图片,如果不存在则使用 SF Symbols
|
// 尝试设置自定义图片,如果不存在则使用 SF Symbols
|
||||||
if let normalImg = UIImage(named: normalImage), let selectedImg = UIImage(named: selectedImage) {
|
if let normalImg = UIImage(named: normalImage), let _ = UIImage(named: selectedImage) {
|
||||||
// 使用自定义图片
|
// 使用自定义图片(初始显示 off 图片)
|
||||||
button.setImage(normalImg, for: .normal)
|
button.setImage(normalImg, for: .normal)
|
||||||
button.setImage(selectedImg, for: .selected)
|
|
||||||
} else {
|
} else {
|
||||||
// 使用 SF Symbols 作为备用
|
// 使用 SF Symbols 作为备用
|
||||||
let fallbackIcons = ["sparkles", "person.circle"]
|
let fallbackIcons = ["sparkles", "person.circle"]
|
||||||
@@ -162,7 +160,6 @@ import SnapKit
|
|||||||
let imageConfig = UIImage.SymbolConfiguration(pointSize: 24, weight: .medium)
|
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: .normal)
|
||||||
button.setImage(UIImage(systemName: iconName, withConfiguration: imageConfig), for: .selected)
|
|
||||||
button.tintColor = .white.withAlphaComponent(0.6)
|
button.tintColor = .white.withAlphaComponent(0.6)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,28 +181,57 @@ import SnapKit
|
|||||||
|
|
||||||
/// Tab 按钮点击事件
|
/// Tab 按钮点击事件
|
||||||
@objc private func tabButtonTapped(_ sender: UIButton) {
|
@objc private func tabButtonTapped(_ sender: UIButton) {
|
||||||
selectedIndex = sender.tag
|
let newIndex = sender.tag
|
||||||
updateTabButtonStates(selectedIndex: sender.tag)
|
|
||||||
|
// 如果点击的是当前已选中的 tab,不做任何操作
|
||||||
|
if newIndex == selectedIndex {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 先更新按钮状态
|
||||||
|
updateTabButtonStates(selectedIndex: newIndex)
|
||||||
|
|
||||||
|
// 再切换 ViewController(使用动画)
|
||||||
|
selectedIndex = newIndex
|
||||||
|
|
||||||
let tabNames = ["动态", "我的"]
|
let tabNames = ["动态", "我的"]
|
||||||
NSLog("[EPTabBarController] 选中 Tab: \(tabNames[sender.tag])")
|
NSLog("[EPTabBarController] 选中 Tab: \(tabNames[newIndex])")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 更新 Tab 按钮状态
|
/// 更新 Tab 按钮状态
|
||||||
private func updateTabButtonStates(selectedIndex: Int) {
|
private func updateTabButtonStates(selectedIndex: Int) {
|
||||||
|
// 禁用按钮交互,避免快速点击
|
||||||
|
tabButtons.forEach { $0.isUserInteractionEnabled = false }
|
||||||
|
|
||||||
for (index, button) in tabButtons.enumerated() {
|
for (index, button) in tabButtons.enumerated() {
|
||||||
let isSelected = (index == selectedIndex)
|
let isSelected = (index == selectedIndex)
|
||||||
button.isSelected = isSelected
|
button.isSelected = isSelected
|
||||||
|
|
||||||
// 如果是 SF Symbols,更新 tintColor
|
// 更新图片状态
|
||||||
if button.tintColor != nil {
|
if let normalImageName = button.accessibilityLabel,
|
||||||
|
let selectedImageName = button.accessibilityHint {
|
||||||
|
// 使用自定义图片
|
||||||
|
let imageName = isSelected ? selectedImageName : normalImageName
|
||||||
|
if let image = UIImage(named: imageName) {
|
||||||
|
button.setImage(image, for: .normal)
|
||||||
|
} else {
|
||||||
|
// 如果自定义图片不存在,使用 SF Symbols
|
||||||
|
button.tintColor = isSelected ? .white : .white.withAlphaComponent(0.6)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 使用 SF Symbols(备用方案)
|
||||||
button.tintColor = isSelected ? .white : .white.withAlphaComponent(0.6)
|
button.tintColor = isSelected ? .white : .white.withAlphaComponent(0.6)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 选中状态动画
|
// 选中状态动画
|
||||||
UIView.animate(withDuration: 0.2) {
|
UIView.animate(withDuration: 0.25, delay: 0, options: [.curveEaseInOut], animations: {
|
||||||
button.transform = isSelected ? CGAffineTransform(scaleX: 1.1, y: 1.1) : .identity
|
button.transform = isSelected ? CGAffineTransform(scaleX: 1.1, y: 1.1) : .identity
|
||||||
}
|
}, completion: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 延迟恢复按钮交互,避免动画期间的重复点击
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
|
||||||
|
self.tabButtons.forEach { $0.isUserInteractionEnabled = true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,15 +240,18 @@ import SnapKit
|
|||||||
globalEventManager = GlobalEventManager.shared()
|
globalEventManager = GlobalEventManager.shared()
|
||||||
globalEventManager?.setupSDKDelegates()
|
globalEventManager?.setupSDKDelegates()
|
||||||
|
|
||||||
// 设置房间最小化视图
|
// TODO: v0.2 版本暂时禁用房间最小化视图(无房间功能)
|
||||||
|
// 后续版本可通过 Build Configuration 或版本号判断是否启用
|
||||||
|
/*
|
||||||
if let containerView = view {
|
if let containerView = view {
|
||||||
globalEventManager?.setupRoomMiniView(on: containerView)
|
globalEventManager?.setupRoomMiniView(on: containerView)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// 注册社交分享回调
|
// 注册社交分享回调
|
||||||
globalEventManager?.registerSocialShareCallback()
|
globalEventManager?.registerSocialShareCallback()
|
||||||
|
|
||||||
NSLog("[EPTabBarController] 全局管理器设置完成")
|
NSLog("[EPTabBarController] 全局管理器设置完成(v0.2 - 无 MiniRoom)")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 设置初始 ViewController(未登录状态)
|
/// 设置初始 ViewController(未登录状态)
|
||||||
@@ -283,25 +312,31 @@ import SnapKit
|
|||||||
|
|
||||||
/// 设置登录后的 ViewControllers
|
/// 设置登录后的 ViewControllers
|
||||||
private func setupLoggedInViewControllers() {
|
private func setupLoggedInViewControllers() {
|
||||||
// 创建真实的 ViewController(OC 类)
|
// 只在 viewControllers 为空或不是正确类型时才创建
|
||||||
let momentVC = EPMomentViewController()
|
if viewControllers?.count != 2 ||
|
||||||
momentVC.tabBarItem = createTabBarItem(
|
!(viewControllers?[0] is EPMomentViewController) ||
|
||||||
title: "动态",
|
!(viewControllers?[1] is EPMineViewController) {
|
||||||
normalImage: "tab_moment_normal",
|
|
||||||
selectedImage: "tab_moment_selected"
|
// 创建真实的 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]
|
||||||
|
NSLog("[EPTabBarController] 登录后 ViewControllers 创建完成 - Moment & Mine")
|
||||||
|
}
|
||||||
|
|
||||||
let mineVC = EPMineViewController()
|
|
||||||
mineVC.tabBarItem = createTabBarItem(
|
|
||||||
title: "我的",
|
|
||||||
normalImage: "tab_mine_normal",
|
|
||||||
selectedImage: "tab_mine_selected"
|
|
||||||
)
|
|
||||||
|
|
||||||
viewControllers = [momentVC, mineVC]
|
|
||||||
selectedIndex = 0
|
selectedIndex = 0
|
||||||
|
|
||||||
NSLog("[EPTabBarController] 登录后 ViewControllers 设置完成 - Moment & Mine")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user