如何在 Swiftui 中显示来自 ObservableObject 的数据
How to show data from a ObservableObject in Swiftui
我正在尝试使用 SwiftUI 制作一个小型社交媒体应用程序。
我创建了一个名为 user 的 ObservableObject class 和一个 Sign up 视图,其中 var 获取值。当我试图在我的 ProfilView 中显示数据时发生错误。
线程 1:致命错误:未找到用户类型的 ObservableObject。 User 的 View.environmentObject(_:) 作为此视图的祖先可能缺失。
Home 是主视图,当按下按钮时,我会在视图之间切换,AppInformation 中的 bool 更改。
struct ProfileView: View {
@EnvironmentObject var appUser: User
@State var beschreibung: String = ""
@State var benutzername: String = ""
@State var name: String = ""
var body: some View {
init() {
benutzername = appUser.username
name = appUser.name
}
ZStack {
Rectangle()
.frame(width: 400, height: 720)
.cornerRadius(50)
.foregroundColor(.gray)
.overlay(
HStack {
Image(systemName: "person.circle")
.resizable()
.frame(width: 100, height: 100)
.onTapGesture {
print("pressed")
}
.padding(20)
.overlay(
ZStack{
Rectangle()
.frame(width: 20, height: 20)
.offset(x: 35, y: -35)
.foregroundColor(.white)
Image(systemName: "plus.circle.fill")
.resizable()
.frame(width: 30, height: 30)
.offset(x: 35, y: -35)
.foregroundColor(.blue)
}
)
VStack {
Text(benutzername)
.font(.largeTitle)
.frame(width: 240 ,alignment: .leading)
.offset(x: -10, y: -25)
.lineLimit(1)
Text(name)
.frame(width: 220, alignment: .leading)
.offset(x: -15,y: -20)
.lineLimit(1)
}
}
.frame(width: 400, height: 720, alignment: .topLeading)
)
.padding()
ZStack {
Rectangle()
.foregroundColor(.secondary)
.frame(width: 380, height: 510)
.cornerRadius(45)
}
.frame(width: 400, height: 700, alignment: .bottom)
.padding()
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
}
}
class User: ObservableObject{
@Published var username: String = ""
@Published var name: String = ""
var password: String = ""
@Published var email: String = ""
@Published var beschreibung: String = ""
}
@State var isSecured: Bool = true
@State var noPassword: Int = 0
@State var noEmail: Int = 0
@State var noUsername: Int = 0
@State var noName: Int = 0
@State var password: String = ""
@State var username: String = ""
@State var name: String = ""
@State var email: String = ""
@EnvironmentObject var appInfo: AppInformation
@EnvironmentObject var appUser: User
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 25)
.frame(width: 380, height: 650)
.overlay(Text("Erstelle Accout ")
.foregroundColor(.white)
.frame(width: 360, height: 510, alignment: .top)
.font(.headline))
ZStack {
VStack {
TextField("Username", text: $username)
.frame(width:180 ,height:40 ,alignment: .center)
.multilineTextAlignment(.center)
.font(.headline)
.background(Color.gray.opacity(0.25))
.clipShape(Capsule())
.foregroundColor(.white)
.border(.red, width: CGFloat(noUsername))
Spacer()
.frame(height: 35)
TextField("Full name", text: $name)
.frame(width:180 ,height:40 ,alignment: .center)
.multilineTextAlignment(.center)
.font(.headline)
.background(Color.gray.opacity(0.25))
.clipShape(Capsule())
.foregroundColor(.white)
.border(.red, width: CGFloat(noName))
Spacer()
.frame(height: 35)
TextField("Email", text: $email)
.frame(width:180 ,height:40 ,alignment: .center)
.multilineTextAlignment(.center)
.font(.headline)
.background(Color.gray.opacity(0.25))
.clipShape(Capsule())
.foregroundColor(.white)
.border(.red, width: CGFloat(noEmail))
Spacer()
.frame(height: 35)
HStack {
Spacer()
.frame(width: 37)
if isSecured {
SecureField("Password", text: $password)
.frame(width:180 ,height:40 ,alignment: .center)
.multilineTextAlignment(.center)
.font(.headline)
.background(Color.gray.opacity(0.25))
.clipShape(Capsule())
.foregroundColor(.white)
.border(.red, width: CGFloat(noPassword))
} else {
TextField("Password", text: $password)
.frame(width:180 ,height:40 ,alignment: .center)
.multilineTextAlignment(.center)
.font(.headline)
.background(Color.gray.opacity(0.25))
.clipShape(Capsule())
.foregroundColor(.white)
.border(.red, width: CGFloat(noPassword))
}
ZStack {
Button(" ") {
isSecured.toggle()
print(isSecured)
}
Image(systemName: self.isSecured ? "eye" : "eye.slash")
.foregroundColor(.gray)
}
}
Spacer()
.frame(height: 60)
Button("Erstellen"){
if username == "" {
noUsername = 1
if name == "" {
noName = 1
if email == "" {
noEmail = 1
if password == "" {
noPassword = 1
}
}
else if password == "" {
noPassword = 1
}
}
else if email == "" {
noEmail = 1
if password == "" {
noPassword = 1
}
}
else if password == "" {
noPassword = 1
}
}
else if name == "" {
noName = 1
if email == "" {
noEmail = 1
if password == "" {
noPassword = 1
}
}
else if password == "" {
noPassword = 1
}
}
else if email == "" {
noEmail = 1
if password == "" {
noPassword = 1
}
}
else if password == "" {
noPassword = 1
}
else {
appUser.username = username
appUser.email = email
appUser.password = password
appUser.name = name
appInfo.finished = true
}
}
.font(.headline)
.frame(width: 150, height: 50)
.background(.blue)
.foregroundColor(.white)
.clipShape(Capsule())
}
}
}
}
}
class AppInformation: ObservableObject{
@Published var home: Bool = true
@Published var camera: Bool = false
@Published var friends: Bool = false
@Published var profil: Bool = false
@Published var showBar: Bool = true
@Published var finished: Bool = false
}
struct Home: View {
@EnvironmentObject var appInfo: AppInformation
@EnvironmentObject var appUser: User
var body: some View {
ZStack {
if appInfo.finished {
if appInfo.home {
HomeView()
}
else if appInfo.camera {
MakePostView()
}
else if appInfo.friends {
FriendsView()
}
else if appInfo.profil {
ProfileView()
.environmentObject(appUser)
}
if appInfo.showBar {
NavigationBar()
}
}
else {
ErstellenView().environmentObject(appInfo)
.environmentObject(appUser)
}
}
}
}
User 应该是一个结构,并使其在 appInfo 对象上发布 属性。我们通常只有一个环境对象保存模型结构,我们通常称它为模型而不是 appInfo。
appInfo 中的大部分现有 bool 应该位于 View 结构中的 @State var bool 中,相关的可以一起放在 @State var 结构中,您可以使用变异函数来操作数据。
在 ProfileView
中,视图主体中不能有 init()
。
完全删除 init()
,直接使用 appUser.username
和 appUser.name
,例如:
Text(appUser.username)
和 Text(appUser.name)
。这就是使用 User
ObservableObject
模型的目的。无需创建
局部变量。当您尝试在 init()
中访问 appUser
时,EnvironmentObject
将不会准备就绪,它将是 ...missing as an ancestor of this view
。换句话说,你不应该在 init()
.
中使用 EnvironmentObject
我正在尝试使用 SwiftUI 制作一个小型社交媒体应用程序。 我创建了一个名为 user 的 ObservableObject class 和一个 Sign up 视图,其中 var 获取值。当我试图在我的 ProfilView 中显示数据时发生错误。
线程 1:致命错误:未找到用户类型的 ObservableObject。 User 的 View.environmentObject(_:) 作为此视图的祖先可能缺失。
Home 是主视图,当按下按钮时,我会在视图之间切换,AppInformation 中的 bool 更改。
struct ProfileView: View {
@EnvironmentObject var appUser: User
@State var beschreibung: String = ""
@State var benutzername: String = ""
@State var name: String = ""
var body: some View {
init() {
benutzername = appUser.username
name = appUser.name
}
ZStack {
Rectangle()
.frame(width: 400, height: 720)
.cornerRadius(50)
.foregroundColor(.gray)
.overlay(
HStack {
Image(systemName: "person.circle")
.resizable()
.frame(width: 100, height: 100)
.onTapGesture {
print("pressed")
}
.padding(20)
.overlay(
ZStack{
Rectangle()
.frame(width: 20, height: 20)
.offset(x: 35, y: -35)
.foregroundColor(.white)
Image(systemName: "plus.circle.fill")
.resizable()
.frame(width: 30, height: 30)
.offset(x: 35, y: -35)
.foregroundColor(.blue)
}
)
VStack {
Text(benutzername)
.font(.largeTitle)
.frame(width: 240 ,alignment: .leading)
.offset(x: -10, y: -25)
.lineLimit(1)
Text(name)
.frame(width: 220, alignment: .leading)
.offset(x: -15,y: -20)
.lineLimit(1)
}
}
.frame(width: 400, height: 720, alignment: .topLeading)
)
.padding()
ZStack {
Rectangle()
.foregroundColor(.secondary)
.frame(width: 380, height: 510)
.cornerRadius(45)
}
.frame(width: 400, height: 700, alignment: .bottom)
.padding()
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
}
}
class User: ObservableObject{
@Published var username: String = ""
@Published var name: String = ""
var password: String = ""
@Published var email: String = ""
@Published var beschreibung: String = ""
}
@State var isSecured: Bool = true
@State var noPassword: Int = 0
@State var noEmail: Int = 0
@State var noUsername: Int = 0
@State var noName: Int = 0
@State var password: String = ""
@State var username: String = ""
@State var name: String = ""
@State var email: String = ""
@EnvironmentObject var appInfo: AppInformation
@EnvironmentObject var appUser: User
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 25)
.frame(width: 380, height: 650)
.overlay(Text("Erstelle Accout ")
.foregroundColor(.white)
.frame(width: 360, height: 510, alignment: .top)
.font(.headline))
ZStack {
VStack {
TextField("Username", text: $username)
.frame(width:180 ,height:40 ,alignment: .center)
.multilineTextAlignment(.center)
.font(.headline)
.background(Color.gray.opacity(0.25))
.clipShape(Capsule())
.foregroundColor(.white)
.border(.red, width: CGFloat(noUsername))
Spacer()
.frame(height: 35)
TextField("Full name", text: $name)
.frame(width:180 ,height:40 ,alignment: .center)
.multilineTextAlignment(.center)
.font(.headline)
.background(Color.gray.opacity(0.25))
.clipShape(Capsule())
.foregroundColor(.white)
.border(.red, width: CGFloat(noName))
Spacer()
.frame(height: 35)
TextField("Email", text: $email)
.frame(width:180 ,height:40 ,alignment: .center)
.multilineTextAlignment(.center)
.font(.headline)
.background(Color.gray.opacity(0.25))
.clipShape(Capsule())
.foregroundColor(.white)
.border(.red, width: CGFloat(noEmail))
Spacer()
.frame(height: 35)
HStack {
Spacer()
.frame(width: 37)
if isSecured {
SecureField("Password", text: $password)
.frame(width:180 ,height:40 ,alignment: .center)
.multilineTextAlignment(.center)
.font(.headline)
.background(Color.gray.opacity(0.25))
.clipShape(Capsule())
.foregroundColor(.white)
.border(.red, width: CGFloat(noPassword))
} else {
TextField("Password", text: $password)
.frame(width:180 ,height:40 ,alignment: .center)
.multilineTextAlignment(.center)
.font(.headline)
.background(Color.gray.opacity(0.25))
.clipShape(Capsule())
.foregroundColor(.white)
.border(.red, width: CGFloat(noPassword))
}
ZStack {
Button(" ") {
isSecured.toggle()
print(isSecured)
}
Image(systemName: self.isSecured ? "eye" : "eye.slash")
.foregroundColor(.gray)
}
}
Spacer()
.frame(height: 60)
Button("Erstellen"){
if username == "" {
noUsername = 1
if name == "" {
noName = 1
if email == "" {
noEmail = 1
if password == "" {
noPassword = 1
}
}
else if password == "" {
noPassword = 1
}
}
else if email == "" {
noEmail = 1
if password == "" {
noPassword = 1
}
}
else if password == "" {
noPassword = 1
}
}
else if name == "" {
noName = 1
if email == "" {
noEmail = 1
if password == "" {
noPassword = 1
}
}
else if password == "" {
noPassword = 1
}
}
else if email == "" {
noEmail = 1
if password == "" {
noPassword = 1
}
}
else if password == "" {
noPassword = 1
}
else {
appUser.username = username
appUser.email = email
appUser.password = password
appUser.name = name
appInfo.finished = true
}
}
.font(.headline)
.frame(width: 150, height: 50)
.background(.blue)
.foregroundColor(.white)
.clipShape(Capsule())
}
}
}
} }
class AppInformation: ObservableObject{
@Published var home: Bool = true
@Published var camera: Bool = false
@Published var friends: Bool = false
@Published var profil: Bool = false
@Published var showBar: Bool = true
@Published var finished: Bool = false
}
struct Home: View {
@EnvironmentObject var appInfo: AppInformation
@EnvironmentObject var appUser: User
var body: some View {
ZStack {
if appInfo.finished {
if appInfo.home {
HomeView()
}
else if appInfo.camera {
MakePostView()
}
else if appInfo.friends {
FriendsView()
}
else if appInfo.profil {
ProfileView()
.environmentObject(appUser)
}
if appInfo.showBar {
NavigationBar()
}
}
else {
ErstellenView().environmentObject(appInfo)
.environmentObject(appUser)
}
}
}
}
User 应该是一个结构,并使其在 appInfo 对象上发布 属性。我们通常只有一个环境对象保存模型结构,我们通常称它为模型而不是 appInfo。
appInfo 中的大部分现有 bool 应该位于 View 结构中的 @State var bool 中,相关的可以一起放在 @State var 结构中,您可以使用变异函数来操作数据。
在 ProfileView
中,视图主体中不能有 init()
。
完全删除 init()
,直接使用 appUser.username
和 appUser.name
,例如:
Text(appUser.username)
和 Text(appUser.name)
。这就是使用 User
ObservableObject
模型的目的。无需创建
局部变量。当您尝试在 init()
中访问 appUser
时,EnvironmentObject
将不会准备就绪,它将是 ...missing as an ancestor of this view
。换句话说,你不应该在 init()
.
EnvironmentObject