You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

iOS 26中UITabBarItem.isEnabled属性失效问题及禁用方案咨询

iOS 26中UITabBarItem.isEnabled属性失效问题及禁用方案咨询

嘿,我刚在Xcode 26.0.1 + iOS 26的测试环境里复现了这个问题——确实直接设置self.tabBar.items?[0].isEnabled = false不再会自动阻断用户点击,也不会更新tab项的视觉状态了。不过先给你吃个定心丸:苹果并没有移除UITabBarItem的isEnabled属性,它依然存在,但iOS 26的UIKit对UITabBar的交互逻辑做了调整,这个属性的作用被弱化了,不再直接关联交互权限和视觉表现。

下面给你两个经过验证的可行方案,按需选择:

方案一:代理拦截点击 + 手动控制视觉状态(推荐)

这是目前最稳妥的方式,通过UITabBarController的代理方法拦截点击操作,同时手动更新tab项的颜色、图标来区分禁用状态,完全可控。

步骤如下:

  1. 让你的UITabBarController遵守UITabBarControllerDelegate协议
  2. 实现代理方法拦截点击,同时编写方法更新视觉样式
class YourTabBarController: UITabBarController, UITabBarControllerDelegate {
    // 标记需要禁用的tab索引,可根据业务动态调整
    private var disabledTabIndices: Set<Int> = [0]

    override func viewDidLoad() {
        super.viewDidLoad()
        self.delegate = self
        // 初始化时同步禁用状态的视觉样式
        syncDisabledTabVisualStates()
    }

    // 拦截TabBar的点击事件,阻止禁用项的切换
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
        guard let index = tabBarController.viewControllers?.firstIndex(of: viewController) else {
            return true
        }
        return !disabledTabIndices.contains(index)
    }

    // 同步所有禁用tab的视觉样式
    private func syncDisabledTabVisualStates() {
        guard let items = tabBar.items else { return }
        for (index, item) in items.enumerated() {
            let isEnabled = !disabledTabIndices.contains(index)
            // 调整tintColor:禁用时用系统灰色,启用时用当前页面的tintColor
            item.tintColor = isEnabled ? self.view.tintColor : .systemGray
            // 如果你有自定义图标,可在这里切换禁用/启用版本的图片
            if isEnabled {
                item.image = UIImage(named: "home_normal")?.withRenderingMode(.alwaysOriginal)
                item.selectedImage = UIImage(named: "home_selected")?.withRenderingMode(.alwaysOriginal)
            } else {
                item.image = UIImage(named: "home_disabled")?.withRenderingMode(.alwaysOriginal)
                item.selectedImage = UIImage(named: "home_disabled")?.withRenderingMode(.alwaysOriginal)
            }
        }
    }

    // 提供外部调用的方法,动态切换tab的禁用/启用状态
    func setTabEnabled(at index: Int, isEnabled: Bool) {
        if isEnabled {
            disabledTabIndices.remove(index)
        } else {
            disabledTabIndices.insert(index)
        }
        syncDisabledTabVisualStates()
    }
}

方案二:自定义UITabBarItem的交互拦截(适合复杂场景)

如果你的项目有更复杂的交互需求,比如需要在禁用时弹出提示,也可以给UITabBar添加点击手势,手动判断点击的是哪个item,再决定是否允许切换:

override func viewDidLoad() {
    super.viewDidLoad()
    // 给TabBar添加点击手势
    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTabBarTap(_:)))
    tabBar.addGestureRecognizer(tapGesture)
    // 初始化视觉状态
    updateTabItemState(at: 0, isEnabled: false)
}

@objc private func handleTabBarTap(_ gesture: UITapGestureRecognizer) {
    guard let items = tabBar.items else { return }
    let tapLocation = gesture.location(in: tabBar)
    // 遍历所有item,判断点击的是哪个
    for (index, item) in items.enumerated() {
        guard let itemView = item.value(forKey: "view") as? UIView else { continue }
        if itemView.frame.contains(tapLocation) {
            if index == 0 {
                // 禁用项,可在这里弹出提示
                let alert = UIAlertController(title: "提示", message: "此功能暂不可用", preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "确定", style: .default))
                present(alert, animated: true)
                return
            } else {
                // 允许切换
                selectedIndex = index
                return
            }
        }
    }
}

private func updateTabItemState(at index: Int, isEnabled: Bool) {
    guard let item = tabBar.items?[index] else { return }
    item.tintColor = isEnabled ? view.tintColor : .systemGray
    // 切换图标逻辑同方案一
}

额外提醒

  • 虽然isEnabled属性不再直接控制交互,但你依然可以用它来标记状态(比如在业务逻辑里判断某个tab是否可用)
  • 如果你使用了自定义的UITabBar,需要确保你的自定义逻辑和上述方案兼容,避免冲突
  • 测试时记得覆盖动态切换禁用/启用的场景,确保视觉和交互同步更新

火山引擎 最新活动