gpt4 book ai didi

ios - 在 Swift 中声明具有类型约束的属性

转载 作者:可可西里 更新时间:2023-11-01 02:17:19 25 4
gpt4 key购买 nike

我需要在我的应用程序中创建自定义字段框架。我为名为 FieldType 的字段定义了一个协议(protocol)并用它扩展UITextFieldUIButton是不同类型的字段。

现在我想为字段创建一个容器 View ,所以我希望容器能够将其字段元素引用为 UIView s 和 FieldType s,我想知道是否有一种简洁的方法来定义它接收到的元素类型是特定的 UIView实现了 FieldType协议(protocol)?

我可以有 FieldContainerView接受 UIView s 或 FieldType s 并手动检查它是否也与另一个匹配 guard语句,但感觉有点麻烦。

我尝试了两种方法:

1) 定义自定义中介 FieldViewType

想法是有 FieldViewType扩展 UIView直接与 FieldType所以它可能作为 UITextField: FieldType 的一般情况有用和 UIButton: FieldType .但正如该代码示例清楚地表明的那样,这是行不通的。

protocol FieldType {
var showError: Bool { get set }
var isEmpty: Bool { get set }
}

class CustomTextField: UITextField, FieldType {}
class CustomButtonField: UIButton, FieldType {}

let textField = CustomTextField()
textField is UIView // True
textField is FieldType // True

let buttonField = CustomButtonField()
buttonField is UIView // True
buttonField is FieldType // True

class FieldView: UIView, FieldProtocol {}

let field = FieldView()
field is UIView // True
field is FieldProtocol // True

textField is FieldView // False
buttonField is FieldView // False

2) 使用泛型

我可以像这样定义一个符合要求的通用类型 <FieldViewType: UIView where FieldViewType: FieldType> ,但我看不出在哪里可以最好地解决我的问题。如果我在类级别定义它

class FieldContainerView<FieldViewType: UIView where FieldViewType: FieldType>: UIView {
var fields = [FieldViewType]()
func addField(FieldViewType: field) {
fields.append(field)
}
}

我需要为每个要使用的字段类型声明一次容器类,并且不能在同一个容器中使用 2 种字段类型。

另一种选择是使用addField 在函数级别定义类型约束。

class FieldContainerView: UIView {
var fields = [UIView]()
func addField<FieldViewType: UIView where FieldViewType: FieldType>(FieldViewType: field) {
fields.append(field)
}
}

然后将每个元素都转换到fields中至 FieldType必要时,我会知道类型转换将始终有效,因为 addField是向容器添加元素的唯一方法。但这也感觉太麻烦了。

感觉最好的解决方法是能够定义 FieldViewTypetypealias ,但这似乎不受支持。或者有 UIView用协议(protocol)定义,以便更好地混合,但 UIKit 不是以这种方式构建的。

最佳答案

所以目前看来还没有办法在属性声明中创建类型约束。我不知道为什么,但我对语言实现一无所知。

我寻求一种变通方法,其中 FieldType 也有一个带有默认实现的 view: UIView 属性。

新的 FieldType 声明:

protocol FieldType {
var showError: Bool { get set }
var isEmpty: Bool { get set }
var view: UIView { get }
}

extension FieldType where Self: UIView {
var view: UIView {
return self
}
}

这样,在符合 FieldType 协议(protocol)之前,您从 UIKit 层次结构中的哪个类继承并不重要,只要您在某个地方有 UIView 作为您的 super 类,您将拥有可访问的 view 属性。

这感觉像是一种解决方法,但至少它为需要对象的 FieldTypeUIView 属性的集合节省了双重声明。

关于ios - 在 Swift 中声明具有类型约束的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36113819/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com