镜像Obj-C的@property (nonatomic) NSArray <SomeProtocol>* items;
哪个项为UIView
子类的最佳方法是什么?
在下面的示例中,我希望存储一系列符合协议的UIKit
组件(例如UILabel
,UIButton
等),但是这样给出错误Protocol can only be used as a generic constraint because it has Self or associated type requirements
有哪些替代方法可以对此进行建模?
示例游乐场:
import UIKit
/// Protocol representing a form field model
protocol FieldRepresentable {}
/// Protocol representing a form UI control
protocol FormControllable {
associatedtype FieldRepresentable
init(model: FieldRepresentable)
var model: FieldRepresentable { get }
}
/// Example label model
class FormLabelElement: FieldRepresentable {}
/// Example label UI control
class FormLabel: UILabel, FormControllable {
required init(model: FormLabelElement) {
self.model = model
super.init(frame: CGRect.zero)
}
let model: FormLabelElement
required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }
}
/// Example form
class Form: UIView {
// Error here
var fields: [FormControllable]?
}
答案 0 :(得分:0)
Nate Cook建议
一种简单易行的方法是从
init
中移除相关类型并使其FieldRepresentable
可用。每个符合类型基本上都必须验证它知道如何处理传递的特定import UIKit /// Protocol representing a form field model that is used to instantiate a UI control protocol FieldRepresentable: class {} /// Protocol representing a form UI control protocol FormControllable: class { init?(model: FieldRepresentable) } /// Example label model class FormLabelElement: FieldRepresentable {} /// Example label UI control class FormLabel: UILabel, FormControllable { required init?(model: FieldRepresentable) { guard let model = model as? FormLabelElement else { return nil } self.model = model super.init(frame: CGRect.zero) } let model: FormLabelElement required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } /// Example form class Form: UIView { var fields = [FormControllable]() } // Create a form let form = Form() let labelModel = FormLabelElement() let labelField = FormLabel(model: labelModel)! form.fields.append(labelField) print(form.fields) form.fields.forEach { (field) in if field is FormLabel { print("We have a label field") } }
类型。我认为你会失去一点类型的安全/表达,但会获得拥有非均匀阵列的能力
因此该方法的最终版本最终成为:
$scope.$watch('data.sliderDelegate', function(newVal, oldVal) {
if (newVal != null) {
$scope.data.sliderDelegate.on('slideChangeEnd', function() {
$scope.data.currentPage = $scope.data.sliderDelegate.activeIndex;
if($scope.data.currentPage == $scope.data.lastSlide){
$scope.data.sliderDelegate.lockSwipeToNext();
}
else{
$scope.data.sliderDelegate.unlockSwipeToNext();
}
$scope.$apply();
});
}
});
或者,如果您的模型协议足够通用,Soroush建议
一个想法是将您的字段可表示类型转换为枚举,因为有一定数量的表单字段元素类型
然后你只需要一个将枚举变成表单元素的大开关
您可以获取一组字段数据案例并将它们映射到表单元素数组