首先,让我解释一下我的应用及其流程。应用程序打开,用户创建配置文件(将所有数据存储在类型[String: Any]
的字典中)。用户单击“创建”后,会将它们发送到控制台屏幕(显示用户输入的部分信息,例如通过segue
显示的名称)。这是一个标签,让他们编辑他们的个人资料(姓名,体重,地址等)。当用户编辑他们的信息(更改他们的姓名,体重等)时,它还应该更新控制台页面上显示的信息。
我的主要问题是,我如何构建它,以便所有选项卡视图都可以普遍使用数据。更具体地说,数据不是数据的实例或副本。我创建了一个名为Person
的类,其中包含所有变量(firstName
,lastName
等)。我在UIViewController
类声明之前尝试将person类的实例声明为变量,但它不允许我使用UITextField
.text
属性(因为他们还没有被创造出来......?)。
这是我的Person类...
class Person {
var firstName: String
var lastName: String
var phoneNumber: String
var weight: Int
var gender: String
var streetAddress: String
var cityState: String
init(firstName: String, lastName: String, phoneNumber: String, weight: Int, gender: String, streetAddress: String, cityState: String) {
self.firstName = firstName
self.lastName = lastName
self.phoneNumber = phoneNumber
self.weight = weight
self.gender = gender
self.streetAddress = streetAddress
self.cityState = cityState
}
}
我还将UITabBarController
归类为TabBarViewController
,因为我已经读过您可以将数据发送到该子类viewController
并使其普遍适用于所有嵌入的标签。我对这一切是如何运作感到茫然。
我为可能会问一个重复的问题而道歉...我已经查看/研究了这个问题,而且我找不到适合我特定情况的合适解决方案。
更新了将数据保存为CoreData
...
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext = appDelegate.persistentContainer.viewContext
let userInfo = PInfo(firstName: firstNameField.text, lastName: lastNameField.text, cityState: cityStateField.text, streetAddress: streetAddressField.text, gender: genderInputField.text, userWeight: 200)
save(withPersonInfo: userInfo, withContext: managedContext)
我能够访问各种viewControllers
中的数据,但它会将其作为单个项目数组返回给我...理想情况下,我希望将它们作为{{{{ 1}}对,因此我可以轻松地将它们设置为显示,并且可以在key:value
Edit Profile
中进行修改。
谢谢!
答案 0 :(得分:1)
一个非常简单的解决方案是为您的应用委派一个person
属性,初始化为空Person。这解决了这个问题,因为每个类都可以访问该属性:
let p = (UIApplication.shared.delegate as! AppDelegate).person
此外,p
通过引用获取此Person,因此对其属性的任何更改都会反映回person
属性本身,以供下一个视图控制器查看(和变异)。 / p>
一个更复杂,令人满意的解决方案,因为只有一个用户需要配置,所以Person类本身会将shared
个人实例作为单例分配。 (在SO上搜索以了解如何在Swift中实现Singleton。)同样,该单例将是普遍可用的:
let p = Person.shared()
答案 1 :(得分:0)
一个解决方案是Delegates
。获取数据的类将设置您的委托,以及希望获得该委托的任何其他人。
事实上:我认为使用Delegate + CoreData
可能会让你免于麻烦;侦听数据然后保存该数据。现在你的其他控制器将进行快速获取(核心数据是如此快速的人:)为那个用户场景)
一些代码:
class PersonDetail: NSManagedObject { // this is how your coreData's Entity should look like
@NSManaged public var firstname: String?
@NSManaged public var lastname: String?
// add the other fields, such as weight
@nonobjc public class func fetchRequest() -> NSFetchRequest<PersonDetail> {
return NSFetchRequest<PersonDetail>(entityName: "PersonDetail")
}
}
// This struct would to get the data from the user
struct PInfo {
var firstname:String?
var lastname:String?
}
// this function would get an instance of that PInfo
// for example var p = PInfo(firstname:"Stack",lastname:"Overflow")
func save(withPersonInfo p:PInfo, withContext context:NSManagedObjectContext) {
let entityDescription = NSEntityDescription.entity(forEntityName: "PersonDetail", in: context)
let managedObject = NSManagedObject(entity: entityDescription!, insertInto: context) as! PersonDetail
// this is where I am passing data into the entity
managedObject.firstname = p.firstname
managedObject.lastname = p.lastname
try? context.save() // use the proper do {} catch, I was saving time lol :)
}
// when you fetch from coreData you have an instance of PInfo
func fetchSingleUser(withContext context:NSManagedObjectContext) -> PInfo {
let request:NSFetchRequest<PersonDetail> = PersonDetail.fetchRequest()
let coreData_items = try? context.fetch(request)
guard let items = coreData_items,
let firstItem = items.first // since we only have one user
else { fatalError("Error while querying") }
return PInfo(firstname: firstItem.firstname, lastname:firstItem.lastname)
}