You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UserDefaults更新后UIBarButtonItem标题未更新问题排查

问题原因及解决方案

问题根源

  1. 你仅更新了totalPrice变量,但未将新值同步到UIBarButtonItem的自定义按钮标题上。你的扩展创建的UIBarButtonItem基于自定义UIButton,变量变更不会自动关联到按钮UI。
  2. viewDidAppear仅在视图首次显示时执行一次,后续totalPrice变化时不会触发该方法更新按钮。

解决步骤

1. 保留自定义按钮的引用

在视图控制器中声明变量存储你的UIBarButtonItem实例:

var cartBarButton: UIBarButtonItem!

2. 创建按钮时赋值引用

替换你原本创建按钮的代码,将实例赋值给上述变量:

// 示例:根据你的实际图片/标题/事件修改
let cartImage = UIImage(named: "cart_icon")!
cartBarButton = UIBarButtonItem.button(image: cartImage, title: "¥0.00", target: self, action: #selector(handleCartTap))
navigationItem.rightBarButtonItem = cartBarButton

3. 编写按钮标题更新方法

新增方法专门处理按钮标题的更新,同时处理自定义视图的类型转换:

private func updateCartButtonTitle() {
    guard let customButton = cartBarButton.customView as? UIButton else { return }
    // 格式化价格显示,可根据需求调整格式
    customButton.setTitle(String(format: "¥%.2f", totalPrice), for: .normal)
    customButton.sizeToFit() // 标题长度变化后重新适配尺寸
}

4. 触发更新逻辑

  • 在viewDidAppear中更新totalPrice后调用更新方法:
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    totalPrice = viewModel.getTotalPrice() ?? 0
    updateCartButtonTitle()
}
  • 若totalPrice在其他场景(如购物车商品增减)更新,需在对应位置同样调用updateCartButtonTitle()。

进阶优化(MVVM场景)

如果使用MVVM架构,可让ViewModel中的totalPrice成为可观察属性,自动响应变化:

// ViewModel代码
import Combine

class CartViewModel {
    @Published var totalPrice: Double = 0
    
    func getTotalPrice() -> Double? {
        guard let products = UserDefaults.standard.getBasketProductsDefault() else { return 0 }
        var total: Double = 0
        for product in products {
            total += Double(product.totalAmount) * product.productPrice
        }
        return total
    }
    
    // 可补充方法:当购物车商品变化时更新totalPrice
    func refreshTotalPrice() {
        totalPrice = getTotalPrice() ?? 0
    }
}

在视图控制器中监听变化:

import Combine

class CartViewController: UIViewController {
    private var cancellables = Set<AnyCancellable>()
    var viewModel = CartViewModel()
    var cartBarButton: UIBarButtonItem!

    override func viewDidLoad() {
        super.viewDidLoad()
        // 监听totalPrice变化自动更新按钮
        viewModel.$totalPrice
            .sink { [weak self] _ in
                self?.updateCartButtonTitle()
            }
            .store(in: &cancellables)
    }
}

内容的提问来源于stack exchange,提问作者themmfa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 22:01:27