Swift - 代码重用

时间:2017-07-28 06:51:24

标签: swift uitextfield uilabel

我正在寻求关于代码重用的一些建议。

我有一个视图控制器(在此阶段)有12个标签和12个文本字段。

对于这些标签和字段中的每一个,都有重复的代码行(请参阅下面的注释行)。

我想知道在创建标签和文本字段时重用代码行的最佳方法,而不是一直重写它们。

我已经查看了扩展,创建了一个类,并且还对常见的代码行进行了子类化,但是我一直在打墙。

我已经使用一个类填充文本字段并理解它是如何工作的,但我似乎无法在该类中添加其他常用属性。感谢

示例:

class PaddedTextField: UITextField {

    let padding = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5);

    override func textRect(forBounds bounds: CGRect) -> CGRect {
        return UIEdgeInsetsInsetRect(bounds, padding)
    }

    override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
        return UIEdgeInsetsInsetRect(bounds, padding)
    }

    override func editingRect(forBounds bounds: CGRect) -> CGRect {
        return UIEdgeInsetsInsetRect(bounds, padding)
    }

    func createText(with text: String) -> UITextField {
        let txtField = UITextField()
        txtField.backgroundColor = .clear
        txtField.widthAnchor.constraint(equalToConstant: 250).isActive = true
        txtField.layer.borderWidth = 1
        txtField.layer.borderColor = UIColor(r: 203, g: 203, b: 203).cgColor
        txtField.layer.cornerRadius = 5
        txtField.layer.masksToBounds = true
        txtField.placeholder = text
        txtField.isEnabled = true
        return txtField
    }
} 

** 更新 **

感谢所有评论。

我现在通过在我的填充类中添加一个func来重复使用常见的代码行。

不幸的是,文本字段填充不再有效。

let textFieldA = PaddedTextField().createText(with: "placeholder text...")

因此,这行代码无需添加字段填充...

let textFieldB = PaddedTextField()
textFieldB.backgroundColor = .clear
textFieldB.widthAnchor.constraint(equalToConstant: 250).isActive = true
textFieldB.layer.borderWidth = 1
textFieldB.layer.borderColor = UIColor(r: 203, g: 203, b: 203).cgColor
textFieldB.layer.cornerRadius = 5
textFieldB.layer.masksToBounds = true
textFieldB.placeholder = "textFieldB placeholder text..."
textFieldB.isEnabled = true

...这适用于字段填充,但不能重复使用公共代码行。

select 
sku.entity_id, sku.sku, #get sku and entity
productName.value, #get name
description.value #get description
from 
catalog_product_entity as sku,
catalog_product_entity_varchar as productName,
catalog_product_entity_text as description
where
productName.attribute_id = 73 
and
sku.entity_id = productName.entity_id
and
description.attribute_id = 75
and
sku.entity_id = description.entity_id;

我不确定哪些部分我错了/不明白。感谢。

3 个答案:

答案 0 :(得分:2)

使用这些重复属性创建UILabel子类可能是最有效和最干净的方法。

第二种方法是创建 工厂

例如:

private class func factoryLabel() -> UILabel
{
   let label = UILabel()
   label.backgroundColor = .clear
   label.widthAnchor.constraint(equalToConstant: 150).isActive = true
   label.font = LabelC.font.withSize(18)
   label.textAlignment = .left

   return label
}

...

let LabelB = myClass.factoryLabel()
LabelB.text = “This is my 2nd label of 12“

此处的示例是类func,您需要将其称为静态函数,即使用类的名称。

<强>更新

在您的更新中,您并未完全使用工厂,您正在创建UITextField的子类,并在该子类内部分解UITextField(即分解您的子类)

由于您已经拥有工厂的子类并不是必需的,因此请将您的课程更改为:

class PaddedTextField:UITextField
{
    private let padding:UIEdgeInsets = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5);

    init(with text:String)
    {
        super.init(frame:CGRect.zero)
        backgroundColor = .clear
        widthAnchor.constraint(equalToConstant:250).isActive = true
        layer.borderWidth = 1
        layer.borderColor = UIColor(r: 203, g: 203, b: 203).cgColor
        layer.cornerRadius = 5
        layer.masksToBounds = true
        placeholder = text
        isEnabled = true
    }

    required init?(coder aDecoder:NSCoder)
    {
        return nil
    }

    override func textRect(forBounds bounds:CGRect) -> CGRect
    {
        return UIEdgeInsetsInsetRect(bounds, padding)
    }

    override func placeholderRect(forBounds bounds:CGRect) -> CGRect
    {
        return UIEdgeInsetsInsetRect(bounds, padding)
    }

    override func editingRect(forBounds bounds:CGRect) -> CGRect
    {
        return UIEdgeInsetsInsetRect(bounds, padding)
    }
}

现在实例化它:

let textFieldA = PaddedTextField(with: "placeholder text...")

答案 1 :(得分:1)

简单解决方案是将文本字符串作为参数传递并返回标签的函数:

func createLabel(with text: String) -> UILabel
{
   let label = UILabel()
   label.backgroundColor = .clear
   label.widthAnchor.constraint(equalToConstant: 150).isActive = true
   label.font = LabelC.font.withSize(18)
   label.textAlignment = .left
   label.text = text
   return label
}

let labelA = createLabel(with: "This is my 1st label of 12")
let labelB = createLabel(with: "This is my 2nd label of 12")
let labelC = createLabel(with: "This is my 3rd label of 12")

** 更新 **

在子类化UITextField的情况下,我建议覆盖两个指定的init方法,并为附加设置添加常用方法,并使用类方法设置text属性。如果在Interface Builder中使用init(coder

创建文本字段,则还可以考虑其他设置
class PaddedTextField: UITextField {

    class func create(with text: String) -> PaddedTextField
    {
        let field = PaddedTextField()
        field.text = text
        return field
    }

    let padding = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5);

    override func textRect(forBounds bounds: CGRect) -> CGRect {
        return UIEdgeInsetsInsetRect(bounds, padding)
    }

    override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
        return UIEdgeInsetsInsetRect(bounds, padding)
    }

    override func editingRect(forBounds bounds: CGRect) -> CGRect {
        return UIEdgeInsetsInsetRect(bounds, padding)
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    func setup() {
        self.backgroundColor = .clear
        self.widthAnchor.constraint(equalToConstant: 250).isActive = true
        self.layer.borderWidth = 1
        self.layer.borderColor = UIColor(white: 0.796, alpha: 1.0).cgColor
        self.layer.cornerRadius = 5
        self.layer.masksToBounds = true
        self.placeholder = text
        self.isEnabled = true
    }
}


let labelA = PaddedTextField.create(with: "This is my 1st label of 12")
let labelB = PaddedTextField.create(with: "This is my 2nd label of 12")
let labelC = PaddedTextField.create(with: "This is my 3rd label of 12")

答案 2 :(得分:0)

在这种情况下,我会使用stackview(这里有一个很棒的talk),所以你不必一直受到填充等的困扰。

您可以创建如下函数:

func mkInput(with text: String) -> (UILabel, UITextField) {
    let label: UILabel
    let textField: UITextField
    // config these as you want...
    return (label, textField)
}

您可以使用以下字符串创建集合:

let inputs: [(UILabel, UITextField)] = labelStrings.map { mkInput(with: $0) }

等等。 :)