我试图做...在基类中使用泛型函数
在我的应用我有很多看起来很像带着一帮自定义功能(在突出改变颜色的表单字段ECT )。
我想创建一个包装类,它抽象所有这些代码,然后从中继承来实现我不同的输入类型,如日期输入和文本输入。
继承的类只需要为它的类型设置正确的输入控件。
我已经试过
这更像是伪代码。我一直在尝试几个小时,但我只是不明白如何实现我所需要的
我想我从一个基类开始,这需要定义一个对输入控件的引用,以及每个方法的一些方法将覆盖,如能够设置或获得当前值
class BaseInput<T>: UIView {
let label = UILabel()
let control: T
... A bunch of methods for layout and stuff ...
func setControlValue(_ value: U) {
print("I'm not a real input yet, so i can't do that")
}
}
然后,我创建一个日期输入的继承类。它使用一个基本的标签控制,并在内部将使用的UIDatePicker设定值
class DateInput: BaseInput<UILabel> {
override init() {
self.control = UILabel()
}
override func setControlValue(_ value: Date) {
MyGlobalDateFormatter.string(format:value)
}
}
,另一个用于文本输入字段
class TextInput: BaseInput<UITextField> {
override init() {
self.control = UITextField()
}
override func setControlValue(_ value: String) {
control.textLabel!.text = value
}
}
什么,我最终要的是能力初始化一个输入组件,并且MyInput.control
属性为该特定输入的正确类,并且setControlValue
方法接受正确类型的数据(即字符串,整数或日期,具体取决于控件的类型)
我相信这可以使用泛型的解决,但我真的很难理解如何。如果任何人都能指出我会朝着正确的方向发展,那将是很棒的。
注意:我不期望或不希望任何人为我编写所有代码。伪代码足以让我全力以赴。
尝试1:
protocol CustomControl {
associatedtype Control
associatedtype Value
var control : Control { get }
var label : UILabel { get }
func setControlValue(_ value: Value)
}
class AbstractInputField: UIView {
// This class contains all the setup
// for the label and wrapping UI View
}
class TextInputField: AbstractInputField, CustomControl {
typealias Control = UITextField
typealias Value = String
let control = UITextField()
func setControlValue(_ value: String) {
control.text = value
}
}
class DateInputField: AbstractInputField, CustomControl {
typealias Control = UILabel
typealias Value = String
let control = UILabel()
private let picker = UIDatePicker()
func setControlValue(_ value: Date) {
control.text = GlobalDateFormatter.string(from: value)
}
.. Also in this class it's a bunch of date picker methods ..
}
在其他地方,如果我做的:
override func viewDidLoad() {
let firstInput = makeControl("text")
firstInput.label.text = "First name"
firstInput.setControlValue(myUser.first_name)
let dobInput = makeControl("date")
dobInput.label.text = "Date of birth"
dobInput.setControlValue(myUser.dob)
}
func makeControl(controlType: String) -> CustomControl {
// Im using strings just for testing, i'd probably make this an enum or something
if controlType == "text" {
return TextInputField()
} else {
return DateInputField()
}
}
我得到的错误:'协议 'CustomControl' 只能作为一种通用的约束,因为它有自我或相关的类型要求
我最终试图实现的是一个非常简单的API来输入我可以设置标签文本,并设置输入值。我的应用程序的其余部分不关心它是文本字段,textview还是完整的自定义输入类型。我的应用程序想要使用协议(或某种基类)来说明它具有这些方法的属性。
也许我很愚蠢。
有趣。谢谢你,我会快速玩这个:) – TRG
在这种情况下你会如何处理BaseClass?理想情况下,我可以在同一个实例上使用'input.control'和'input.label'来分别获取标签或控件。 我应该在'BaseInputField'上实现'CustomControl',并让控件和值类型像'UILabel'&'String'一样泛型并在其他类中重写? 我想另一种选择是根据我想访问的内容将我的实例投射到'BaseInputField'或'CustomControl',但这看起来不是正确的选项。 – TRG
我真的不明白你想达到什么目的。当日期输入和文本输入字段可以有标签或文本字段时,我会创建两个符合'CustomControl'协议的不同类。 –