Swift3 将不同子类的实例传递到Swift 3中的另一个ViewController

Swift3 将不同子类的实例传递到Swift 3中的另一个ViewController,swift3,uiviewcontroller,subclass,Swift3,Uiviewcontroller,Subclass,我试图将已创建用户的实例传递到另一个视图控制器。问题在于被传递的用户取决于选择的用户类型。我的意思是,我已经创建了主类用户的许多子类。例如:Guest、VIP、Child等,所以当在第一页上创建实例时,它是为该用户创建的子类。如果不将second view controller user属性设置为Type user,我无法了解如何将用户传递给second view controller。问题是类型用户没有子类拥有的所有属性,所以在第二页中,我无法访问子类可能拥有的所有属性。这是我目前设置的示例:

我试图将已创建用户的实例传递到另一个视图控制器。问题在于被传递的用户取决于选择的用户类型。我的意思是,我已经创建了主类用户的许多子类。例如:Guest、VIP、Child等,所以当在第一页上创建实例时,它是为该用户创建的子类。如果不将second view controller user属性设置为Type user,我无法了解如何将用户传递给second view controller。问题是类型用户没有子类拥有的所有属性,所以在第二页中,我无法访问子类可能拥有的所有属性。这是我目前设置的示例:

第一屏/视图控制器

var entrantData: People? 
var entrantSelected: EntrantType = .none

@IBAction func generatePass(_ sender: UIButton) {
    do{
switch entrantSelected {
        case .freechildguest: entrantData = try Child(dateOfBirth: "\(dobTextField.text!)")
        case .classicguest: entrantData = ClassicGuest()
        case .maintenance: entrantData = try Maintenance(NameAddress(firstName: firstNameTextField.text, lastName: lastNameTextField.text, streetAddress: streetAddressTextField.text, city: cityTextField.text, state: stateTextField.text, zipCode: zipCodeTextField.text, entrantType: .maintenance))
        default: break 
        }
} catch let error {
        showAlert(title: "Error", message: "\(error)")
}

}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let destViewController = segue.destination as? TicketViewController {
        destViewController.dataFromForm = entrantData 
    }
}
class TicketViewController: UIViewController {
var dataFromForm: People?
第二屏幕/视图控制器

var entrantData: People? 
var entrantSelected: EntrantType = .none

@IBAction func generatePass(_ sender: UIButton) {
    do{
switch entrantSelected {
        case .freechildguest: entrantData = try Child(dateOfBirth: "\(dobTextField.text!)")
        case .classicguest: entrantData = ClassicGuest()
        case .maintenance: entrantData = try Maintenance(NameAddress(firstName: firstNameTextField.text, lastName: lastNameTextField.text, streetAddress: streetAddressTextField.text, city: cityTextField.text, state: stateTextField.text, zipCode: zipCodeTextField.text, entrantType: .maintenance))
        default: break 
        }
} catch let error {
        showAlert(title: "Error", message: "\(error)")
}

}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let destViewController = segue.destination as? TicketViewController {
        destViewController.dataFromForm = entrantData 
    }
}
class TicketViewController: UIViewController {
var dataFromForm: People?
所以在第二个视图控制器中,我现在有dataFromForm中的用户数据,但我希望它在它的子类中,这样我就可以得到它的属性,这些属性只被划分在它的子类中。例如,维护用户具有child和classicGuest没有的firstname属性


我想我可以创建子类在User super类中使用的所有属性,但我觉得这违背了创建具有自己独特属性的子类的要点。

解决此问题的一个方法是在
TicketViewController
上保留类型为
的属性,并且在尝试访问只有某个子类具有,请尝试将
People
实例条件下转换为适当的子类

以下是如何实现这一目标的基本示例:

if let vip = dataFromForm as? VIP {
   //access VIP properties
} else if let guest = dataFromForm as? Guest {
   //access guest properties
}

解决此问题的一种方法是在
TicketViewController
上保留类型为
People
的属性,并且在尝试访问只有某个子类具有的属性时,尝试将
People
实例条件下转换为相应的子类

以下是如何实现这一目标的基本示例:

if let vip = dataFromForm as? VIP {
   //access VIP properties
} else if let guest = dataFromForm as? Guest {
   //access guest properties
}

您可以做的另一件事是将其转换为协议本身。在某些情况下,当有多个子类符合同一协议时,这可能会更容易

if let entrant = entrantData as? Nameable {
    fullNameLabel.text = entrant.fullName
}

因此,上面的代码不会在child或classicGuest上执行,因为它们不符合可命名协议。

您可以做的另一件事是向下转换到协议本身。在某些情况下,当有多个子类符合同一协议时,这可能会更容易

if let entrant = entrantData as? Nameable {
    fullNameLabel.text = entrant.fullName
}

因此,上面的代码不会在child或classicGuest上执行,因为它们不符合可命名协议。

是的,当然,如果让我将guest设置为具有票证名称的默认标签文本,我可以使用这种方式,但对于维护类型,我可以让标签使用该用户的名字。非常感谢大卫!不用担心,欢迎光临!如果您发现我的答案有用,请考虑接受它。当然,这样我可以使用,如果让客户设置有默认标签文本的机票名称,但对于维护类型I可以获得标签使用该用户FrestNew。非常感谢大卫!不用担心,欢迎光临!如果你觉得我的答案有用,请考虑接受。