**背景:**我正在使用Core Data处理应用用户设置的永久存储。我的设置之一是Color
值,我正在将其转换为RGB值,并将其存储为由Core Data管理的InitialsImageColor
类型对象的属性。Color
是使用ColorPicker
在Form
视图中选择的。
**问题:**我在视图的init()
声明中初始化了一个变量imageColor
。编译器抛出一个错误,称“Variable 'self.imageColor' used before been initialize”5次。为了清楚起见,以下是相关的代码部分和注解:
struct SettingsView: View {
// Access the managed object context for saving changes to Core Data
@Environment(\.managedObjectContext) var moc
// Load stored InitialsImageColor objects from Core Data
@FetchRequest(sortDescriptors: []) var colorSetting: FetchedResults<InitialsImageColor>
// A Color variable for the ColorPicker View to bind to
@State private var imageColor: Color
// A String variable for the Form View's .searchable modifier to bind to
@State private var searchText: String = ""
// A Bool variable to change to make the .sheet containing SettingsView to disappear
@Binding var showSettings: Bool
// An initializer to set the starting value for the ColorPicker View to use
init() {
imageColor = Color( // This line throws error
red: colorSetting.first?.r ?? 255.0, // This line throws error
green: colorSetting.first?.g ?? 255.0, // This line throws error
blue: colorSetting.first?.b ?? 255.0, // This line throws error
opacity: colorSetting.first?.a ?? 1.0 // This line throws error
)
}
1.这怎么可能呢?变量的第一次使用是在初始化器中。这个错误不应该发生。
1.我该怎么做才能修好它?
最初,我尝试在imageColor
的声明中初始化它,但当然没有成功,因为它使用另一个变量来得出它的值,并且作用域在视图的body
之外。我将它放在init()
声明中来解决这个问题,然后发生了这种情况。
2条答案
按热度按时间dw1jzc5e1#
这里你的代码有几个问题。首先,
imageColor
有一个a@State
属性 Package 器,这意味着你实际上想这样初始化它:不过,您也可以在声明中轻松地这样写:
因为第二个问题是,你期望fetch请求在init期间发生。事实并非如此。你可以也应该期望SwiftUI视图被初始化和销毁很多次,超出你的控制范围。记住这个原理,你可以看到在初始化时执行fetch请求是没有意义的。它将在视图的
body
被求值时执行。更好的解决方案可能是将颜色定义为自定义绑定,而不是单独的状态变量,然后您可以将其传递给其他视图:
(我在这里留下了你的255个值,因为我刚刚从问题中复制过来)
f0brbegy2#
我找到了一个变通方法,经过思考,我意识到实际上并不需要将
imageColor
初始化到持久化数据对象(我一直在考虑使用与涉及UserDefaults
的旧尝试相关的范例),所以我在声明中初始化了它,如下所示:@State private var imageColor: Color = .white
然后我仅仅更新了初始化器中的值(根本没有改变我的代码**[但请参见编辑]**)。
然而,这产生了类似的错误,它现在告诉我另一个变量
@Binding var showSettings: Bool
正在做同样的事情:“变量'self.showSettings'在初始化之前使用”。我也找到了一个解决方法。我没有使用它来消除.sheet,而是简单地使用dismiss关键帧声明了一个环境变量,如下所示:@Environment(\.dismiss) var dismiss
然后我用我的
Done
按钮调用它,而不是设置showSettings = false
。**EDIT:**构建并打开视图后,我收到以下警告:“访问StateObject的对象,而没有安装在视图上。这将每次创建一个新示例。”它的行为与警告指示的一样。所以我删除了初始化器,并将其代码放在
Form
视图的.onAppear
修饰符中(我还将nil合并更改为强制展开,因为我在运行属性设置代码之前使用了if
块来计算!colorSetting.isEmpty
)。