对于很多操作,我需要检查label.text、textView.text、textField.text等的内容是否为零。
所以我创建了一些扩展:
extension UILabel {
func getText() -> String {
return self.text ?? ""
}
}
extension UITextField {
func getText() -> String {
return self.text ?? ""
}
}
extension UITextView {
func getText() -> String {
return self.text ?? ""
}
}扩展是非常多余的。类似的情况是,我需要将Int、Double、Float等转换为另一种数字格式。我想要的是一个简单的toInt(),在出了问题时返回-1或0。
那么,如何为toString()或toInt()创建泛型函数呢?我在苹果文档中读到了关于扩展和仿制药的文章,但我没有找到解决问题的方法。
最后,我尝试用相同的扩展扩展UIView,因为它是UILabel等的超类,但我不能调用getText()。
那么,创建泛型扩展的好方法是什么呢?
发布于 2018-03-28 13:53:08
这里有一些可疑的东西:我不希望任何toInt()函数在出错时只返回-1或0。Swift有一个很好的选择系统是有原因的,并且返回-1或0引入了几个明显的陷阱。我也不知道您计划如何在getText()上实现UIView。很多视图都没有文本。我不知道这个实现意味着什么,也不知道会做什么。
因此,我将忽略这两个细节,将重点放在主要问题上,这似乎是扩展的冗余。有一个更干净的方法,通过协议扩展,减少重复。
protocol TextProviding {
var text: String? { get }
}
extension TextProviding {
// Following your example here. I would prefer calling
// this a `var textOrEmpty: String` but same idea.
func getText() -> String {
return text ?? ""
}
}
// To conform additional types, you just need 1 line
extension UILabel: TextProviding { }
extension UITextField: TextProviding { }编辑:正如一些人指出的,在extension UITextView: TextProviding { }中使用上面的代码是行不通的,因为UITextView的text是一个String!,而不是String?。不幸的是,这意味着如果您希望这也适用于UITextView,您应该将var text要求重命名为其他东西(这意味着您需要几行额外的代码来手动遵守UILabel和< code >D13)。
protocol TextProviding {
var string: String? { get }
}
extension TextProviding {
var stringOrEmpty: String {
return string ?? ""
}
}
extension UILabel: TextProviding {
var string: String? { return text }
}
extension UITextField: TextProviding {
var string: String? { return text }
}
extension UITextView: TextProviding {
var string: String? { return text }
}发布于 2018-03-28 13:49:57
对于第一个问题,您应该只扩展UIView并检查它是标签、文本字段还是带有if let的文本视图。
extension UIView {
func getText() -> String {
if let label = self as? UILabel {
return label.text ?? ""
} else if let textField = self as? UITextField {
return textField.text ?? ""
} else if let textView = self as? UITextView {
return textView.text ?? ""
}
return ""
}
}与创建协议相比,这种方法的优点是您可以轻松地扩展它,即使文本/标题可以用另一种方法检索,例如,使用UIButton。
[...]
else if let button = self as? UIButton {
return button.title(for: .normal) ?? ""
}发布于 2018-03-28 15:22:22
这个单行比这里发布的所有其他答案减少了冗余代码(您想要的)。不需要疯狂的状态-检查或多个扩展。
extension UIView {
func getText() -> String? {
return self.responds(to: #selector(getter: UILabel.text)) ?
self.perform(#selector(getter: UILabel.text))?.takeUnretainedValue() as? String : nil
}
}https://stackoverflow.com/questions/49536268
复制相似问题