具有动态返回类型的表单输入

时间:2017-10-13 09:40:07

标签: swift generics swift4

我想开发一个动态表单输入,它可能只是一个UITextField或UIDatePicker。表单输入应使用类型(枚举)初始化,因此返回String或Date,具体取决于初始化的类型。也许以后我会想要添加更多特定类型返回其他东西。

使用Swift 4执行此操作的最佳做​​法是什么?您将在何处存储数据(如firstname,lastname,birthdate)?在控制器?通用类型是否可能成为解决方案?

Cheerio

编辑10月18日

感谢用户Palle的支持!最终的解决方案会是这样的:

FormItem.swift

// enum with types for inputs
enum FormItemType: Int {
  case text = 0
  case date = 1
}

// enum with types of values
enum FormInputValue {
  case text(String)
  case date(Date)
}

// FormItem holds value, label and input
class FormItem: UIView {
  var value: FormInputValue?
  var label: FormLabel?
  var input: FormInput?
}

FormInput.swift

// Protocol to delegate the change to the controller
protocol FormInputDelegate: NSObjectProtocol {
  func inputDidChange(value: FormInputValue)
}

// FormInput holds the actual input
class FormInput: UIView {

  var formInput: FormInput?
  var delegate: FormInputDelegate?

  // Init FormInput with type and optional value
  convenience init(type: FormItemType, value: FormInputValue?) {  
    switch type {
      case .text(let text)?:
        self.initTextInput(label: label, value: text)
        break
      case .date(let date)?:
        self.initDateInput(label: label, value: date)
        break
      case .none:
        break;
    }
  }

  // Init specific String input field
  fileprivate func initTextInput (label: String, value: String?) {
    formInput = FormTextInput(label: label, value: value)
    self.addSubview(formInput!)
  }

  // Init specific Date input field
  fileprivate func initDateInput (label: String, value: Date?) {
    formInput = FormDateInput(label: label, value: value)
    self.addSubview(formInput!)
  }
}

FormTextInput.swift

// Init actual input with label and optional value
convenience init(label: String, value: String?) {
  [...]
}

CreateViewController.swift

// Create View Controller where FormInputs 
class CreateViewController: UIViewController {

  var firstname: String = "Test 123"

  // Init view controller and add FormItem
  convenience init() {
    let fistnameFormItem = FormItem(type: .text, label: NSLocalizedString("Input.Label.Firstname", comment: ""), value: FormInputValue.text(firstname))
  }
}

1 个答案:

答案 0 :(得分:0)

我会使用单独的输入而不是一个动态输入。

如果您确实需要通用输入,可以使用枚举及其值的相关值:

enum FormInputResult {
    case date(Date)
    case name(firstName: String, lastName: String)
}

在模型 - 视图 - 控制器架构中,名称和生日等数据应存储在数据模型中。控制器应充当模型和视图之间的中介。