在 SwiftUI Xcode 11 Beta 4 中使用可绑定对象保存数据
Saving data using Bindable Object in SwiftUI Xcode 11 Beta 4
总结:
我正在创建一个具有三个视图和相同 "Settings" 按钮的应用程序,该按钮导航到每个视图右上角的列表视图。当我 select 设置图标时,它会在弹出的列表视图中显示一个滑块、一个步进器和一个切换开关。
我能够使用下面的代码来初始化值,虽然 运行 我能够在“设置”视图中更改应用程序的数据,但我遇到的问题是数据不是当我退出设置视图时保留。
Xcode 11 Beta 4 从 didChange 更新为 willChange 作为 BindableObject 更新的一部分,这可能是我的问题的一部分,因为它可能不会以相同的方式实现。
问题:
1) 退出设置视图时,主视图中的数据没有更新。
2) 当我再次 select 设置视图时,它显示初始化值而不是我之前更改的值。
预期结果:
我希望我的配置文件数据使用设置应用程序中定义的新值进行更新
我的数据存储(Profile.swift)
import SwiftUI
import Combine
class Profile: BindableObject {
var willChange = PassthroughSubject<Void, Never>()
var test1 = 16 { willSet { update() }}
var test2: Double = 10 { willSet { update() }}
var test3 = true { willSet { update() }}
func update() {
willChange.send()
}
}
我的设置视图(ProfileSummary.swift)
import SwiftUI
struct ProfileSummary: View {
//var profile: Profile
@ObjectBinding var profile = Profile()
var body: some View {
List {
Stepper(value: $profile.test1, in: 12...22) {
Text("Test1 Size: \(profile.test1)")
}
Text("Quiz Settings")
.bold()
HStack {
Text(" Test2: \(Int(profile.test2))")
Slider(value: $profile.test2, from: 1.0, through: 107.0, by: 1.0)
}
Toggle(isOn: $profile.test3) {
Text(" Change to Test3")
}
}
}
}
#if DEBUG
struct ProfileSummary_Previews: PreviewProvider {
static var previews: some View {
ProfileSummary()
}
}
#endif
我的主要观点(Test_List.swift):
import SwiftUI
import UIKit
struct Test_List : View {
@ObjectBinding var profile: Profile = Profile()
@State var showingProfile = false
var profileButton: some View {
Button(action: { self.showingProfile.toggle() }) {
Text("Settings")
.padding()
}
}
var body: some View {
NavigationView {
VStack(alignment: .center){
Text("Test1: \(profile.test1)")
Text("Test2: \(profile.test2)")
Spacer()
}
.navigationBarTitle(Text("View3"))
.navigationBarItems(trailing: profileButton)
.sheet(isPresented: $showingProfile) {
ProfileSummary()
}
}
}
}
#if DEBUG
struct Test_List_Previews : PreviewProvider {
static var previews: some View {
Test_List()
}
}
#endif
您正在 Test_List
中创建 Profile
:
struct Test_List : View {
@ObjectBinding var profile: Profile = Profile()
然后您将在 ProfileSummary
中创建一个全新的 Profile
:
struct ProfileSummary: View {
//var profile: Profile
@ObjectBinding var profile = Profile()
所以您的 ProfileSummary
视图编辑它创建的 Profile
,而不是 Test_List
创建的 Profile
。
您需要将您在 Test_List
中创建的 Profile
传递给 ProfileSummary
,以便 ProfileSummary
编辑与 Test_List
使用:
struct Test_List : View {
...
.sheet(isPresented: $showingProfile) {
ProfileSummary(profile: self.profile)
// ^^^^^^^^^^^^^^^^^^^^^ add this
}
您可能还应该将 ProfileSummary
更改为 而不是 自己创建一个新的 Profile
,因为这会浪费资源:
struct ProfileSummary: View {
@ObjectBinding var profile: Profile
// ^^^^^^^^^ declare the type; don't set a default value
总结: 我正在创建一个具有三个视图和相同 "Settings" 按钮的应用程序,该按钮导航到每个视图右上角的列表视图。当我 select 设置图标时,它会在弹出的列表视图中显示一个滑块、一个步进器和一个切换开关。
我能够使用下面的代码来初始化值,虽然 运行 我能够在“设置”视图中更改应用程序的数据,但我遇到的问题是数据不是当我退出设置视图时保留。
Xcode 11 Beta 4 从 didChange 更新为 willChange 作为 BindableObject 更新的一部分,这可能是我的问题的一部分,因为它可能不会以相同的方式实现。
问题: 1) 退出设置视图时,主视图中的数据没有更新。
2) 当我再次 select 设置视图时,它显示初始化值而不是我之前更改的值。
预期结果: 我希望我的配置文件数据使用设置应用程序中定义的新值进行更新
我的数据存储(Profile.swift)
import SwiftUI
import Combine
class Profile: BindableObject {
var willChange = PassthroughSubject<Void, Never>()
var test1 = 16 { willSet { update() }}
var test2: Double = 10 { willSet { update() }}
var test3 = true { willSet { update() }}
func update() {
willChange.send()
}
}
我的设置视图(ProfileSummary.swift)
import SwiftUI
struct ProfileSummary: View {
//var profile: Profile
@ObjectBinding var profile = Profile()
var body: some View {
List {
Stepper(value: $profile.test1, in: 12...22) {
Text("Test1 Size: \(profile.test1)")
}
Text("Quiz Settings")
.bold()
HStack {
Text(" Test2: \(Int(profile.test2))")
Slider(value: $profile.test2, from: 1.0, through: 107.0, by: 1.0)
}
Toggle(isOn: $profile.test3) {
Text(" Change to Test3")
}
}
}
}
#if DEBUG
struct ProfileSummary_Previews: PreviewProvider {
static var previews: some View {
ProfileSummary()
}
}
#endif
我的主要观点(Test_List.swift):
import SwiftUI
import UIKit
struct Test_List : View {
@ObjectBinding var profile: Profile = Profile()
@State var showingProfile = false
var profileButton: some View {
Button(action: { self.showingProfile.toggle() }) {
Text("Settings")
.padding()
}
}
var body: some View {
NavigationView {
VStack(alignment: .center){
Text("Test1: \(profile.test1)")
Text("Test2: \(profile.test2)")
Spacer()
}
.navigationBarTitle(Text("View3"))
.navigationBarItems(trailing: profileButton)
.sheet(isPresented: $showingProfile) {
ProfileSummary()
}
}
}
}
#if DEBUG
struct Test_List_Previews : PreviewProvider {
static var previews: some View {
Test_List()
}
}
#endif
您正在 Test_List
中创建 Profile
:
struct Test_List : View { @ObjectBinding var profile: Profile = Profile()
然后您将在 ProfileSummary
中创建一个全新的 Profile
:
struct ProfileSummary: View { //var profile: Profile @ObjectBinding var profile = Profile()
所以您的 ProfileSummary
视图编辑它创建的 Profile
,而不是 Test_List
创建的 Profile
。
您需要将您在 Test_List
中创建的 Profile
传递给 ProfileSummary
,以便 ProfileSummary
编辑与 Test_List
使用:
struct Test_List : View {
...
.sheet(isPresented: $showingProfile) {
ProfileSummary(profile: self.profile)
// ^^^^^^^^^^^^^^^^^^^^^ add this
}
您可能还应该将 ProfileSummary
更改为 而不是 自己创建一个新的 Profile
,因为这会浪费资源:
struct ProfileSummary: View {
@ObjectBinding var profile: Profile
// ^^^^^^^^^ declare the type; don't set a default value