I’m seeing a rendering issue with UITabBarController on iOS 26 (Liquid Glass), and I’d like to confirm whether others can reproduce this or have a workaround.
Summary
If a UITabBarController is recreated while it is fully hidden behind a fullscreen modal, the tab bar renders incorrectly after dismissal.
- Selected tab becomes nearly invisible
- Unselected tabs appear to show both selected and unselected tint colors
- Looks like multiple rendering states are composited incorrectly
This only happens with:
- iOS 26 (Liquid Glass enabled)
- UIKit UITabBarController
It does not reproduce with SwiftUI TabView.
Minimal Reproduction Code
This is a complete, minimal example:
import UIKit
// MARK: - Root
class RootViewController: UIViewController {
private var tabBar: UITabBarController?
private var modalPresented = false
override func viewDidLoad() {
super.viewDidLoad()
installTabBar()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Present once on first appear, simulating an app-launch login flow.
if !modalPresented {
modalPresented = true
presentModal()
}
}
private func installTabBar() {
let tab = UITabBarController()
tab.viewControllers = [
makeTab(title: "Tab 1", systemImage: "1.circle"),
makeTab(title: "Tab 2", systemImage: "2.circle"),
]
tabBar = tab
addChild(tab)
view.addSubview(tab.view)
tab.view.frame = view.bounds
tab.didMove(toParent: self)
}
private func makeTab(title: String, systemImage: String) -> UIViewController {
let vc = UIViewController()
vc.view.backgroundColor = .systemBackground
vc.tabBarItem = UITabBarItem(title: title, image: UIImage(systemName: systemImage), tag: 0)
return vc
}
private func presentModal() {
let modal = ModalViewController()
modal.onDismiss = { [weak self] in
// Recreate the tab bar while it is still fully hidden by the modal.
// This seems to trigger incorrect Liquid Glass rendering.
self?.tabBar?.willMove(toParent: nil)
self?.tabBar?.view.removeFromSuperview()
self?.tabBar?.removeFromParent()
self?.installTabBar() // ← created while invisible
self?.dismiss(animated: true)
}
modal.modalPresentationStyle = .fullScreen
present(modal, animated: true)
}
}
// MARK: - Modal
class ModalViewController: UIViewController {
var onDismiss: (() -> Void)?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
let button = UIButton(type: .system)
button.setTitle("Dismiss", for: .normal)
button.titleLabel?.font = .preferredFont(forTextStyle: .title2)
button.addTarget(self, action: #selector(dismissTapped), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)
NSLayoutConstraint.activate([
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.centerYAnchor.constraint(equalTo: view.centerYAnchor),
])
}
@objc private func dismissTapped() {
onDismiss?()
}
}
Expected Behavior
The tab bar renders normally with correct Liquid Glass appearance:
- Selected tab is clearly visible
- Unselected tabs show only inactive tint
Actual Behavior
- Selected tab becomes nearly invisible
- Unselected tabs show a mix of selected + unselected tint
- The issue resolves after backgrounding and returning to foreground
Observations / Workarounds
The issue does not reproduce if:
- The tab bar is recreated after dismissal:
self.dismiss(animated: true) {
self.installTabBar()
}
- Using SwiftUI TabView
- Using a presentation style that does not fully cover the screen (.pageSheet, etc.)
Question
- Has anyone else encountered this?
- Is there a recommended workaround besides delaying creation until after dismissal?
It seems like Liquid Glass rendering may not initialize correctly when the view is attached while fully obscured, but I’m not sure if this is expected behavior or a bug.