Swift:在UITabViews和&amp ;;之间传递数据允许全局访问数据

时间:2017-04-21 01:12:16

标签: ios swift uitabview

首先,让我解释一下我的应用及其流程。应用程序打开,用户创建配置文件(将所有数据存储在类型[String: Any]的字典中)。用户单击“创建”后,会将它们发送到控制台屏幕(显示用户输入的部分信息,例如通过segue显示的名称)。这是一个标签,让他们编辑他们的个人资料(姓名,体重,地址等)。当用户编辑他们的信息(更改他们的姓名,体重等)时,它还应该更新控制台页面上显示的信息。

我的主要问题是,我如何构建它,以便所有选项卡视图都可以普遍使用数据。更具体地说,数据不是数据的实例或副本。我创建了一个名为Person的类,其中包含所有变量(firstNamelastName等)。我在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中进行修改。

谢谢!

2 个答案:

答案 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)
}