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

SwiftUI中如何通过UserDefaults更新@ObservedResults过滤器并刷新

解决@ObservedResults不随UserDefaults更新的问题

问题原因

你当前的@ObservedResults查询条件是在视图初始化时一次性计算的,直接读取UserDefaults的初始值。当shareSelection通过@AppStorage修改后,这个查询闭包不会重新执行,因此查询结果不会更新。

解决方案

方案1:使用Realm的@Query(推荐,Realm Swift 10.20+版本支持)

@Query支持动态更新查询条件,适配@AppStorage的变化:

@AppStorage("shareSelection") var shareSelection = "BTCUSDT"
@Query(coinModel.self) var coinsResult: [coinModel]

var body: some View {
    Text(coinsResult.first?.s ?? "")
        .onChange(of: shareSelection) { newValue in
            // 当shareSelection变化时,更新查询谓词
            _coinsResult = Query(filter: "s == %@", newValue)
        }
}

// 初始化时设置初始查询
init() {
    _coinsResult = Query(filter: "s == %@", shareSelection)
}

方案2:通过ViewModel手动管理查询(兼容旧版本Realm)

如果你的Realm版本不支持@Query,可以用ObservableObject监听shareSelection变化,手动更新查询:

首先创建ViewModel:

import RealmSwift
import SwiftUI

class CoinViewModel: ObservableObject {
    @AppStorage("shareSelection") var shareSelection = "BTCUSDT" {
        didSet {
            updateQuery()
        }
    }
    @Published var coinsResult: Results<coinModel>!
    
    init() {
        updateQuery()
    }
    
    private func updateQuery() {
        guard let realm = try? Realm() else { return }
        coinsResult = realm.objects(coinModel.self).filter("s == %@", shareSelection)
    }
}

然后在视图中使用:

@StateObject private var viewModel = CoinViewModel()

var body: some View {
    Text(viewModel.coinsResult.first?.s ?? "")
}

额外注意事项

  • 避免直接使用coinsResult[0],当查询结果为空时会触发崩溃,建议用coinsResult.first?.s ?? ""做安全处理。

内容的提问来源于stack exchange,提问作者Engin Çelik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 21:05:32