扩展UITextField以创建可共享组件

时间:2017-12-18 17:10:05

标签: ios swift uikit

我有许多以编程方式添加的UITextField组件,它们似乎都有许多共享行。

我想将这些扩展到某种扩展,以便我可以共享代码并减少重复的行。

我真的很挣扎如何做到这一点。

我在下面添加了一些这些组件的例子,并希望得到一些关于如何实现这一目标的意见......

let usernameTextField: UITextField = {
    let tf = UITextField()
    tf.placeholder = "Username"
    tf.backgroundColor = UIColor(white: 0, alpha: 0.03)
    tf.font = UIFont.systemFont(ofSize: 14)
    tf.borderStyle = .roundedRect
    tf.autocorrectionType = .no
    tf.autocapitalizationType = .none
    tf.spellCheckingType = .no
    tf.addTarget(self, action: #selector(handleTextInputChange), for: .editingChanged)
    tf.addTarget(nil, action:Selector(("firstResponderAction:")), for:.editingDidEndOnExit)
    return tf
}()

let passwordTextField: UITextField = {
    let tf = UITextField()
    tf.placeholder = "Password"
    tf.backgroundColor = UIColor(white: 0, alpha: 0.03)
    tf.font = UIFont.systemFont(ofSize: 14)
    tf.borderStyle = .roundedRect
    tf.autocorrectionType = .no
    tf.autocapitalizationType = .none
    tf.spellCheckingType = .no
    tf.returnKeyType = .done
    tf.isSecureTextEntry = true
    tf.addTarget(self, action: #selector(handleTextInputChange), for: .editingChanged)
    tf.addTarget(nil, action:Selector(("firstResponderAction:")), for:.editingDidEndOnExit)
    return tf
}()

3 个答案:

答案 0 :(得分:1)

没有可共享的组件"问题在这里。唯一的丑陋是你的代码不干("不要重复自己")。所以让它干!只需将常见的重复代码分解为一个可以从所有文本字段创建代码中调用的函数。例如,让我们假设您在override func viewDidLoad() { super.viewDidLoad() func makeTextField() -> UITextField { let tf = UITextField() tf.backgroundColor = UIColor(white: 0, alpha: 0.03) tf.font = UIFont.systemFont(ofSize: 14) tf.borderStyle = .roundedRect tf.autocorrectionType = .no tf.autocapitalizationType = .none tf.spellCheckingType = .no tf.addTarget(self, action: #selector(handleTextInputChange), for: .editingChanged) tf.addTarget(nil, action:Selector(("firstResponderAction:")), for:.editingDidEndOnExit) return tf } let usernameTextField: UITextField = { let tf = makeTextField() tf.placeholder = "Username" return tf }() let passwordTextField: UITextField = { let tf = makeTextField() tf.placeholder = "Password" tf.returnKeyType = .done tf.isSecureTextEntry = true return tf }() // ... do something with text fields here ... } 中执行了所有这些操作。然后你展示的代码可以像这样考虑:

List<WebElement> productThumbs = new WebDriverWait(driver, 500)
    .until(new Function<WebDriver, WebElement>() {
        public WebElement apply(WebDriver driver) {
            return driver.findElements(By.className("product-thumb"));
        }
    });
assertThat(productThumbs.size(), is(greaterThan(0)));

答案 1 :(得分:1)

这是另一种方法。使用扩展名设置公共属性,如此...

extension UITextField{

    func initCommonProperties(withPlaceholder placeholder:String){

        backgroundColor = UIColor(white: 0, alpha: 0.03)
        font = UIFont.systemFont(ofSize: 14)
        borderStyle = .roundedRect
        autocorrectionType = .no
        autocapitalizationType = .none
        spellCheckingType = .no
        addTarget(self, action: #selector(handleTextInputChange), for: .editingChanged)
        addTarget(nil, action:Selector(("firstResponderAction:")), for:.editingDidEndOnExit)
        self.placeholder = placeholder
    }
}

let usernameTextField: UITextField = {
    let tf = UITextField()
    tf.initCommonProperties(withPlaceholder:"Username")
    return tf
}()

let passwordTextField: UITextField = {
    let tf = UITextField()
    tf.initCommonProperties(withPlaceholder:"Password")
    return tf
}()

您也可以使用功能而不是扩展程序

class MyTextFieldUtils{

    static func initCommonProperties(tf:UITextField){

        tf.backgroundColor = UIColor(white: 0, alpha: 0.03)
        tf.font = UIFont.systemFont(ofSize: 14)
        tf.borderStyle = .roundedRect
        tf.autocorrectionType = .no
        tf.autocapitalizationType = .none
        tf.spellCheckingType = .no
        tf.addTarget(self, action: #selector(handleTextInputChange), for: .editingChanged)
        tf.addTarget(nil, action:Selector(("firstResponderAction:")), for:.editingDidEndOnExit)
    }
}

let usernameTextField: UITextField = {
    let tf = UITextField()
    MyTextFieldUtils.initCommonProperties(tf)
    tf.placeholder = "Username"
    return tf
}()

let passwordTextField: UITextField = {
    let tf = UITextField()
    MyTextFieldUtils.initCommonProperties(tf)
    tf.placeholder = "Password"
    return tf
}()

前者的优点是API更简单。缺点是现在所有 UITextField都将获得initCommonProperties函数。

后者的优点是它完全区分了问题,但却以更冗长的代价为代价。但是,您可以通过创建多个函数或多个类(每个函数具有相同的函数)为不同类型的TextBox(或任何控件)创建不同的初始值设定项。

另一种方法是通过扩展创建便利初始化器,如此......

extension UITextField{

    convenience init(withPlaceholder placeholder:String){

        self.init()

        backgroundColor = UIColor(white: 0, alpha: 0.03)
        font = UIFont.systemFont(ofSize: 14)
        borderStyle = .roundedRect
        autocorrectionType = .no
        autocapitalizationType = .none
        spellCheckingType = .no
        addTarget(self, action: #selector(handleTextInputChange), for: .editingChanged)
        addTarget(nil, action:Selector(("firstResponderAction:")), for:.editingDidEndOnExit)
        self.placeholder = placeholder
    }
}

let usernameTextField = UITextField(withPlaceholder:"Username")
let passwordTextField = UITextField(withPlaceholder:"Password")

希望这有帮助!

答案 2 :(得分:-1)

最简单的解决方案就是将init子类化,并在重写的UITextField方法中包含共享行。然后,您将直接创建子类的实例,而不是class MyTextField: UITextField { override init() { super.init() self.backgroundColor = UIColor(white: 0, alpha: 0.03) self.font = UIFont.systemFont(ofSize: 14) self.borderStyle = .roundedRect self.autocorrectionType = .no self.autocapitalizationType = .none tfselfspellCheckingType = .no } } let passwordTextField = MyTextField() ...

示例:

{{1}}