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

SwiftData绑定导致聚焦形状时关闭应用崩溃问题求助

SwiftData绑定与可聚焦元素共存时关闭应用崩溃问题解决

问题描述

当SwiftUI控件(如Slider)绑定SwiftData模型的属性(如Double类型),且视图中存在独立的可聚焦形状(如Circle)时,若关闭应用时Circle处于聚焦状态,应用会触发崩溃,报错信息为:

SwiftData/BackingData.swift:124: Fatal error: Unable to get value - no backing Managed Object

复现条件

  • 基于DocumentGroup封装的文档型应用(测试环境:macOS 14.4.1)
  • 点击Circle使其获得焦点后关闭文档,即可触发崩溃
  • 若将焦点转移至TextField等输入控件,关闭时不会崩溃,说明崩溃与Circle的聚焦状态直接相关

复现代码

import SwiftUI
import SwiftData

@Model
class MyModel {
    init() {}
    var aValue: Double = 1.0
}

@MainActor
struct ContentView: View {
    @Environment(\.modelContext) private var modelContext
    @Query private var myModels:[MyModel]
        
    var body: some View {
        HStack {
            ForEach(myModels) { model in
                Slider(value: Bindable(model).aValue, in: 0...1)
                Circle().focusable()
            }
        }.onAppear(){
            if self.myModels.count == 0 {
                let model = MyModel()
                modelContext.insert(model)
                try? modelContext.save()
            }
        }
    }
}

问题分析

崩溃根源在于:文档关闭时SwiftData托管对象已被销毁,但处于聚焦状态的Circle会干扰视图生命周期的回调顺序,导致Slider的绑定在对象销毁后仍尝试访问其属性——尽管Slider和Circle在视图结构上无直接关联,焦点状态却会影响绑定的释放时机。

解决方案

方法1:视图消失前主动清除焦点

通过@FocusState跟踪焦点状态,在视图即将消失时手动重置,避免聚焦元素干扰绑定释放:

@MainActor
struct ContentView: View {
    @Environment(\.modelContext) private var modelContext
    @Query private var myModels:[MyModel]
    @FocusState private var focusedCircleID: UUID? // 标记聚焦的Circle
    
    var body: some View {
        HStack {
            ForEach(myModels) { model in
                Slider(value: Bindable(model).aValue, in: 0...1)
                Circle()
                    .focusable()
                    .focused($focusedCircleID, equals: model.id) // 绑定焦点状态
            }
        }
        .onAppear(){
            if myModels.isEmpty {
                let model = MyModel()
                modelContext.insert(model)
                try? modelContext.save()
            }
        }
        .onDisappear {
            focusedCircleID = nil // 视图消失前清空焦点
        }
    }
}

方法2:拆分视图封装绑定与焦点状态

将每行的绑定和焦点状态封装到子视图中,让状态管理更独立,确保视图销毁时绑定与焦点同步释放:

@MainActor
struct ContentView: View {
    @Environment(\.modelContext) private var modelContext
    @Query private var myModels:[MyModel]
        
    var body: some View {
        HStack {
            ForEach(myModels) { model in
                ModelRowView(model: model)
            }
        }
        .onAppear(){
            if myModels.isEmpty {
                let model = MyModel()
                modelContext.insert(model)
                try? modelContext.save()
            }
        }
    }
}

// 子视图封装绑定与焦点状态
struct ModelRowView: View {
    @Bindable var model: MyModel
    @FocusState private var isCircleFocused: Bool

    var body: some View {
        HStack {
            Slider(value: $model.aValue, in: 0...1)
            Circle()
                .focusable()
                .focused($isCircleFocused)
        }
        .onDisappear {
            isCircleFocused = false // 子视图消失时清除焦点
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 07:23:15