Xcode26 build app with iOS26, UITabBarController set CustomTabBar issue

Our project using UITabBarController and set a custom tabbar using below code:

        let customTabBar = CustomTabBar(with: dataSource)
        setValue(customTabBar, forKey: "tabBar")

But when using Xcode 26 build app in iOS 26, the tabbar does not show:

above code works well in iOS 18:

below is the demo code:

AppDelegate.swift:

import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    let window: UIWindow = UIWindow()

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        window.rootViewController = TabBarViewController()
        window.makeKeyAndVisible()
        return true
    }
}

CustomTabBar.swift:

import UIKit

class CustomTabBar: UITabBar {
    class TabBarModel {
        let title: String
        let icon: UIImage?
        
        init(title: String, icon: UIImage?) {
            self.title = title
            self.icon = icon
        }
    }
    
    class TabBarItemView: UIView {
        
        lazy var titleLabel: UILabel = {
            let titleLabel = UILabel()
            titleLabel.translatesAutoresizingMaskIntoConstraints = false
            titleLabel.font = .systemFont(ofSize: 14)
            titleLabel.textColor = .black
            titleLabel.textAlignment = .center
            return titleLabel
        }()
        
        lazy var iconView: UIImageView = {
            let iconView = UIImageView()
            iconView.translatesAutoresizingMaskIntoConstraints = false
            iconView.contentMode = .center
            return iconView
        }()
        
        private var model: TabBarModel
        
        init(model: TabBarModel) {
            self.model = model
            super.init(frame: .zero)
            
            setupSubViews()
        }
        
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        private func setupSubViews() {
            addSubview(iconView)
            iconView.topAnchor.constraint(equalTo: topAnchor).isActive = true
            iconView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
            iconView.widthAnchor.constraint(equalToConstant: 34).isActive = true
            iconView.heightAnchor.constraint(equalToConstant: 34).isActive = true
            iconView.image = model.icon
            
            addSubview(titleLabel)
            titleLabel.topAnchor.constraint(equalTo: iconView.bottomAnchor).isActive = true
            titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
            titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
            titleLabel.heightAnchor.constraint(equalToConstant: 16).isActive = true
            titleLabel.text = model.title
        }
    }
    
    private var dataSource: [TabBarModel]
    
    init(with dataSource: [TabBarModel]) {
        self.dataSource = dataSource
        super.init(frame: .zero)
        setupTabBars()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func sizeThatFits(_ size: CGSize) -> CGSize {
        var sizeThatFits = super.sizeThatFits(size)
        let safeAreaBottomHeight: CGFloat = safeAreaInsets.bottom
        sizeThatFits.height = 52 + safeAreaBottomHeight
        return sizeThatFits
    }
    
    private func setupTabBars() {
        backgroundColor = .orange
        
        let multiplier = 1.0 / Double(dataSource.count)
        var lastItemView: TabBarItemView?
        
        for model in dataSource {
            let tabBarItemView = TabBarItemView(model: model)
            addSubview(tabBarItemView)
            tabBarItemView.translatesAutoresizingMaskIntoConstraints = false
            tabBarItemView.topAnchor.constraint(equalTo: topAnchor).isActive = true
            tabBarItemView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
            if let lastItemView = lastItemView {
                tabBarItemView.leadingAnchor.constraint(equalTo: lastItemView.trailingAnchor).isActive = true
            } else {
                tabBarItemView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
            }
            tabBarItemView.widthAnchor.constraint(equalTo: widthAnchor, multiplier: multiplier).isActive = true
            
            lastItemView = tabBarItemView
        }
    }
}

TabBarViewController.swift:

import UIKit

class NavigationController: UINavigationController {
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

class HomeViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .red
        navigationItem.title = "Home"
    }
}

class PhoneViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .purple
        navigationItem.title = "Phone"
    }
}

class PhotoViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .yellow
        navigationItem.title = "Photo"
    }
}

class SettingViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .green
        navigationItem.title = "Setting"
    }
}

class TabBarViewController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let homeVC = HomeViewController()
        let homeNav = NavigationController(rootViewController: homeVC)
        
        let phoneVC = PhoneViewController()
        let phoneNav = NavigationController(rootViewController: phoneVC)
        
        let photoVC = PhotoViewController()
        let photoNav = NavigationController(rootViewController: photoVC)
        
        let settingVC = SettingViewController()
        let settingNav = NavigationController(rootViewController: settingVC)
        
        viewControllers = [homeNav, phoneNav, photoNav, settingNav]

        let dataSource = [
            CustomTabBar.TabBarModel(title: "Home", icon: UIImage(systemName: "house")),
            CustomTabBar.TabBarModel(title: "Phone", icon: UIImage(systemName: "phone")),
            CustomTabBar.TabBarModel(title: "Photo", icon: UIImage(systemName: "photo")),
            CustomTabBar.TabBarModel(title: "Setting", icon: UIImage(systemName: "gear"))
        ]
        let customTabBar = CustomTabBar(with: dataSource)
        
        setValue(customTabBar, forKey: "tabBar")
    }
}

And I have post a feedback in Feedback Assistant(id: FB18141909), the demo project code can be found there. How are we going to solve this problem? Thank you.

@Allen-Chen Did you find any solution for it? I am facing similar issue as well.

@Allen-Chen Not a permanent solution but what you can do is go to Phone settings -> Accessibility -> Motion -> Reduce Motion (Turn on). By this way we are able to see a tabbar with correct functionality.

https://developer.apple.com/forums/profile/Allen-Chen, https://developer.apple.com/forums/profile/Sam_11051996 Dear sir, did you find any solution for it? I am facing similar issue as well.

Hello @Allen-Chen

Are you still having trouble with this issue?

When I run the sample code attached in your bug report, the toolbar shows up exactly as it did in iOS 18. I'm on iOS 26.2.

Let me know.

 Travis Trotto - DTS Engineer

@apvex, @Sam_11051996 Are you still have this issue?

The implementation I received from @Allen-Chen works as expected, if you are experiencing this you it might be something different.

It is worth mentioning that custom elements, like toolbars, may alter or change with device updates. To make sure things never break, use provided frameworks like UIToolbar. You can find an example in this sample code.

Thanks and feel free to provide more info.

 Travis Trotto - DTS Engineer

Xcode26 build app with iOS26, UITabBarController set CustomTabBar issue
 
 
Q