fix: 消除 TabBar 切换时的页面闪烁问题

核心修复:
1. 移除导航栏动画冲突
   - 移除 viewWillAppear 中的 navigationBar 隐藏逻辑
   - ViewController 未包装在 NavigationController 中,调用导航栏方法会触发冗余动画

2. 禁用 UITabBarController 默认切换动画
   - 设置 UITabBarControllerDelegate
   - animationControllerForTransitionFrom 返回 nil 禁用系统动画
   - 使用 UIView.performWithoutAnimation 确保无动画切换

3. 修复背景色未定义导致的白色闪烁
   - 显式设置浅灰色背景作为兜底 (RGB: 0.95, 0.95, 0.97)
   - 添加背景图片的 contentMode 和 clipsToBounds 属性
   - 确保背景图片加载延迟时不显示白色

修复后效果:
- Tab 切换流畅无闪烁,仅保留按钮缩放动画
- 背景色始终一致,无白色背景闪现
- 性能提升,消除多个动画冲突
This commit is contained in:
edwinQQQ
2025-10-10 15:58:23 +08:00
parent 49ac7efa66
commit 8b177e5fad
3 changed files with 60 additions and 37 deletions

View File

@@ -63,8 +63,8 @@
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
//
[self refreshUserInfo];
// ViewController NavigationController
// TabBarController UINavigationController
}
// MARK: - Setup
@@ -82,8 +82,12 @@
}
- (void)setupUI {
//
self.view.backgroundColor = [UIColor colorWithRed:0.95 green:0.95 blue:0.97 alpha:1.0];
UIImageView *bgImageView = [[UIImageView alloc] initWithImage:kImage(@"vc_bg")];
bgImageView.contentMode = UIViewContentModeScaleAspectFill;
bgImageView.clipsToBounds = YES;
[self.view addSubview:bgImageView];
[bgImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self.view);
@@ -201,6 +205,9 @@
- (void)refreshData {
self.currentPage = 1;
[self.momentsData removeAllObjects];
//
[self loadUserInfo];
[self loadUserMoments];
}

View File

@@ -56,14 +56,19 @@
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
//
// [self.navigationController setNavigationBarHidden:YES animated:animated];
// ViewController NavigationController
// TabBarController UINavigationController
}
// MARK: - Setup UI
- (void)setupUI {
//
self.view.backgroundColor = [UIColor colorWithRed:0.95 green:0.95 blue:0.97 alpha:1.0];
UIImageView *bgImageView = [[UIImageView alloc] initWithImage:kImage(@"vc_bg")];
bgImageView.contentMode = UIViewContentModeScaleAspectFill;
bgImageView.clipsToBounds = YES;
[self.view addSubview:bgImageView];
[bgImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self.view);
@@ -75,7 +80,7 @@
make.edges.equalTo(self.view);
}];
//
// TODO:
[self.view addSubview:self.publishButton];
[self.publishButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.view).offset(-20);
@@ -99,7 +104,9 @@
NSString *pageSize = @"10";
NSString *types = @"0,2"; // 0=2=
@kWeakify(self);
[Api momentsRecommendList:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
@kStrongify(self);
self.isLoading = NO;
[self.refreshControl endRefreshing];
@@ -202,7 +209,7 @@
_tableView.delegate = self;
_tableView.dataSource = self;
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_tableView.backgroundColor = self.view.backgroundColor;
_tableView.backgroundColor = [UIColor clearColor]; //
_tableView.estimatedRowHeight = 200;
_tableView.rowHeight = UITableViewAutomaticDimension;
_tableView.showsVerticalScrollIndicator = NO;

View File

@@ -43,6 +43,9 @@ import SnapKit
// TabBar
self.tabBar.isHidden = true
// delegate
self.delegate = self
setupCustomFloatingTabBar()
setupGlobalManagers()
setupInitialViewControllers()
@@ -111,14 +114,12 @@ import SnapKit
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]
@@ -144,35 +145,35 @@ import SnapKit
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
button.adjustsImageWhenHighlighted = false //
// 使 SF Symbols
if let normalImg = UIImage(named: normalImage), let _ = UIImage(named: selectedImage) {
// 使 off
if let normalImg = UIImage(named: normalImage), let selectedImg = UIImage(named: selectedImage) {
// normal selected
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)
let normalIcon = UIImage(systemName: iconName, withConfiguration: imageConfig)
button.setImage(UIImage(systemName: iconName, withConfiguration: imageConfig), for: .normal)
button.setImage(normalIcon, for: .normal)
button.setImage(normalIcon, 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) //
make.size.equalTo(28)
}
button.addTarget(self, action: #selector(tabButtonTapped(_:)), for: .touchUpInside)
@@ -191,8 +192,10 @@ import SnapKit
//
updateTabButtonStates(selectedIndex: newIndex)
// ViewController使
selectedIndex = newIndex
// UITabBarController
UIView.performWithoutAnimation {
selectedIndex = newIndex
}
let tabNames = ["动态", "我的"]
NSLog("[EPTabBarController] 选中 Tab: \(tabNames[newIndex])")
@@ -205,32 +208,23 @@ import SnapKit
for (index, button) in tabButtons.enumerated() {
let isSelected = (index == selectedIndex)
// isSelected
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
// SF Symbols tintColor
if button.currentImage?.isSymbolImage == true {
button.tintColor = isSelected ? .white : .white.withAlphaComponent(0.6)
}
//
UIView.animate(withDuration: 0.25, delay: 0, options: [.curveEaseInOut], animations: {
//
UIView.animate(withDuration: 0.2, delay: 0, options: [.curveEaseOut], animations: {
button.transform = isSelected ? CGAffineTransform(scaleX: 1.1, y: 1.1) : .identity
}, completion: nil)
})
}
//
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
//
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
self.tabButtons.forEach { $0.isUserInteractionEnabled = true }
}
}
@@ -347,6 +341,21 @@ extension EPTabBarController: UITabBarControllerDelegate {
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
NSLog("[EPTabBarController] 选中 Tab: \(item.title ?? "Unknown")")
}
///
func tabBarController(_ tabBarController: UITabBarController,
animationControllerForTransitionFrom fromVC: UIViewController,
to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
// nil 使
return nil
}
///
func tabBarController(_ tabBarController: UITabBarController,
shouldSelect viewController: UIViewController) -> Bool {
// nil animationController
return true
}
}
// MARK: - OC Compatibility