2016-01-16 69 views
-1

我正在制作注册表单应用程序。这让用户可以创建问题并在UITableView中显示创建的问题。用户可以创建两种类型的问题,文本输入(使用文本框)和多项选择(使用分段控件)。这是我为创造这个目的而创建的课程。Swift:使用不同的自定义类型创建数组

class Question { 
var Label: String 
var required: Int 

// create question 
init (Label: String, required: Int) { 
    self.Label = Label 
    self.required = required 

    if (self.required == 0) { 
     self.Label = self.Label + " *" 
    } 
} 
} 

class textInput: Question { 
var placeHolder: String 

init (placeHolder: String, Label: String, required: Int) { 
    self.placeHolder = placeHolder 
    super.init(Label: Label, required: required) 
} 
} 

class multiChoice: Question { 
var answers: [String] 

init(answers: [String], Label: String, required: Int) { 
    self.answers = answers 
    super.init(Label: Label, required: required) 
} 
} 

我将需要用textInput或multiChoice类型填充数组,它将显示在UITableView中。在C++中,您可以使用模板来完成这种任意类型的问题。有没有办法在Swift中做到这一点,如果可以的话,我可以指出如何使用这些类来做到这一点?

回答

1

首先。更改Question类,如下所示:

var required: Bool 

init (Label: String, required: Bool) { 
    self.Label = Label 
    self.required = required 

    if self.required { 
     self.Label = self.Label + " *" 
    } 
} 

接下来,你可以使用[Question]类型的数组实现你在找什么。然后,您可以使用guardif let结构基于班级进行具体操作。

+0

这是行不通的。可以说我有以下几点。 questionsArray:[问题]。比方说,我遍历数组,并得到一个textInput元素。我不能在没有得到错误的情况下调用以下语句,questionsArray [i] .placeholder。 Question基类无权访问“占位符”。这就是为什么我需要一个可以容纳多种自定义类型的数组。 – Malexc

+0

'if let question = questionsArray [i] as? textInput {print(question.placeholder)}' – lukasbalaz7

1

完成你想要的非常干净和类型安全的一种方法是创建一个enum以及将要使用的不同类型的相关值。然后,您可以创建一个enum值的数组,并使用switch解开它们以获得所需的值。

class QuestionBase { 
    var label: String 
    var required: Bool 

    // create question 
    init (label: String, required: Bool) { 
     self.label = label 
     self.required = required 

     if required { 
      self.label = self.label + " *" 
     } 
    } 
} 

class TextInputQuestion: QuestionBase { 
    var placeHolder: String 

    init (placeHolder: String, label: String, required: Bool) { 
     self.placeHolder = placeHolder 
     super.init(label: label, required: required) 
    } 
} 

class MultiChoiceQuestion: QuestionBase { 
    var answers: [String] 

    init(answers: [String], label: String, required: Bool) { 
     self.answers = answers 
     super.init(label: label, required: required) 
    } 
} 

enum Question { 
    case TextInput(TextInputQuestion) 
    case MultiChoice(MultiChoiceQuestion) 
} 

let q1 = TextInputQuestion(placeHolder: "placeholder", label: "q1", required: true) 
let q2 = MultiChoiceQuestion(answers: ["answer1", "answer2"], label: "q2", required: false) 

let questions: [Question] = [.TextInput(q1), .MultiChoice(q2)] 

for question in questions { 
    switch question { 
    case .TextInput(let question): 
     print(question.placeHolder) 
    case .MultiChoice(let question): 
     print(question.answers) 
    } 
} 

enum这种方式非常强大。阵列全部为一种类型:Question。关联的值可以是任何类型。你可以有一个TrueFalsecase,甚至可以有一个Essaycase

我重写了很多你的代码 - 它违反了很多Swift风格的指导原则,这使得它很难阅读。类型名称,例如class名称,应全部为LikeThis(以大写字母开头),而属性应全部位于camelCase(以小写字母开头)。为了更清楚地表达意图,我重新命名了一些类型。您可以采取这些更改或离开他们。

+0

想出了一个更简单的解决方案,类似于上面的评论。就班级的变化而言,除了所需的变量外,我做了许多这些变更。它仍然是一个整数,因为它更容易。 – Malexc

相关问题