首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Swift中UI元素的泛型``getText()‘函数

Swift中UI元素的泛型``getText()‘函数
EN

Stack Overflow用户
提问于 2018-03-28 13:46:15
回答 4查看 966关注 0票数 1

对于很多操作,我需要检查label.texttextView.texttextField.text等的内容是否为零。

所以我创建了一些扩展:

代码语言:javascript
运行
复制
extension UILabel {
    func getText() -> String {
        return self.text ?? ""
    }
}

extension UITextField {
    func getText() -> String {
        return self.text ?? ""
    }
}

extension UITextView {
    func getText() -> String {
        return self.text ?? ""
    }
}

扩展是非常多余的。类似的情况是,我需要将IntDoubleFloat等转换为另一种数字格式。我想要的是一个简单的toInt(),在出了问题时返回-10

那么,如何为toString()toInt()创建泛型函数呢?我在苹果文档中读到了关于扩展仿制药的文章,但我没有找到解决问题的方法。

最后,我尝试用相同的扩展扩展UIView,因为它是UILabel等的超类,但我不能调用getText()

那么,创建泛型扩展的好方法是什么呢?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-03-28 13:53:08

这里有一些可疑的东西:我不希望任何toInt()函数在出错时只返回-1或0。Swift有一个很好的选择系统是有原因的,并且返回-1或0引入了几个明显的陷阱。我也不知道您计划如何在getText()上实现UIView。很多视图都没有文本。我不知道这个实现意味着什么,也不知道会做什么。

因此,我将忽略这两个细节,将重点放在主要问题上,这似乎是扩展的冗余。有一个更干净的方法,通过协议扩展,减少重复。

代码语言:javascript
运行
复制
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 { }中使用上面的代码是行不通的,因为UITextViewtext是一个String!,而不是String?。不幸的是,这意味着如果您希望这也适用于UITextView,您应该将var text要求重命名为其他东西(这意味着您需要几行额外的代码来手动遵守UILabel和< code >D13)。

代码语言:javascript
运行
复制
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 }
}
票数 4
EN

Stack Overflow用户

发布于 2018-03-28 13:49:57

对于第一个问题,您应该只扩展UIView并检查它是标签、文本字段还是带有if let的文本视图。

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
[...]
else if let button = self as? UIButton {
    return button.title(for: .normal) ?? ""
}
票数 0
EN

Stack Overflow用户

发布于 2018-03-28 15:22:22

这个单行比这里发布的所有其他答案减少了冗余代码(您想要的)。不需要疯狂的状态-检查或多个扩展。

代码语言:javascript
运行
复制
extension UIView {
    func getText() -> String? {
        return self.responds(to: #selector(getter: UILabel.text)) ?
        self.perform(#selector(getter: UILabel.text))?.takeUnretainedValue() as? String : nil
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49536268

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档