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

SwiftUI中含搜索与下拉刷新的视图在ObservableObject变更时故障

问题分析与解决

首先你的代码存在一处明显遗漏:MyView中没有声明Model的实例,需要添加@StateObject(iOS 14及以上,用于视图自身持有模型)或者@ObservedObject(如果模型从父视图传入),比如:

struct MyView: View {
    @State var text = ""
    @StateObject var model = Model() // 补上这行
    // ... 其他代码不变
}

接下来是核心问题:当你在.refreshable闭包中同步更新@Published属性时,会立即触发视图重新渲染,而此时下拉刷新的UI动画还处于活跃状态,和searchable的状态更新产生冲突,导致搜索栏异常。你之前用DispatchQueue.main.async无效,是因为.refreshable闭包本身就在主线程执行,重复调度主线程不会改变执行时机。

解决方法

把更新操作放在异步任务中,让下拉刷新动画先完成再更新模型属性,有两种简单实现方式:

方式一:利用Task.yield()让出执行权

让系统先处理完刷新动画的UI更新,再执行模型属性修改:

.refreshable {
    await Task.yield()
    model.prop = "world"
}

方式二:模拟异步操作(贴近真实业务场景)

如果你的实际需求是从网络拉取数据,直接用async/await处理异步任务,自然会延迟属性更新的时机:

.refreshable {
    // 模拟网络请求延迟,实际替换成你的异步数据获取逻辑
    try? await Task.sleep(nanoseconds: 300_000_000) // 0.3秒
    model.prop = "world"
}

这样修改后,下拉刷新动画结束后才会更新模型,不会和searchable的状态产生冲突,搜索栏就能正常工作了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 03:41:43