2017-07-28 65 views
0

我在代码重用的一些建议。斯威夫特 - 代码重用

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

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

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

我已经研究过扩展的,创建一个类,并且继承代码的通用行,但我一直打墙。

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

例如:

let LabelA = UILabel() 
// LabelA.backgroundColor = .clear 
// LabelA.widthAnchor.constraint(equalToConstant: 150).isActive = true 
// LabelA.font = LabelA.font.withSize(18) 
// LabelA.textAlignment = .left 
LabelA.text = “This is my 1st label of 12“ 

let LabelB = UILabel() 
// LabelB.backgroundColor = .clear 
// LabelB.widthAnchor.constraint(equalToConstant: 150).isActive = true 
// LabelB.font = LabelB.font.withSize(18) 
// LabelB.textAlignment = .left 
LabelB.text = “This is my 2nd label of 12“ 

let LabelC = UILabel() 
// LabelC.backgroundColor = .clear 
// LabelC.widthAnchor.constraint(equalToConstant: 150).isActive = true 
// LabelC.font = LabelC.font.withSize(18) 
// LabelC.textAlignment = .left 
LabelC.text = “This is my 3rd label of 12“ 

** 更新 **

感谢所有的意见。

我现在通过添加一个func到我的padding类来重新使用常见的代码行。

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

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 
    } 
} 

所以,这行代码工作不加场填补...

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 

我不确定哪部分我有错/不明白。谢谢。

+0

文本字段中的额外的设置也被认为是“子类的代码共用线,但我一直打墙”。墙壁是什么? – Lawliet

+0

@Lawliet我一直打的墙都是添加func的东西,但没有得到我期望的结果。根据我对OP的更新。 – K1llarney

回答

1

创建具有这些重复属性的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...") 
+0

谢谢,我已经实现了你的答案的一部分,我会更多地关注“工厂”。 – K1llarney

+0

@ K1llarney刚刚更新了我的答案,请看看它。 – zero

+0

谢谢你零,你是一个冠军。 – K1llarney

0

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

您可以创建这样一个功能:

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

等等:

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

比你可以从像字符串创建一个集合。 :)

+0

感谢您的输入亚当。仅供参考...我在设置标签和设置文本字段后使用堆栈视图。我正在使用填充,因为字段是用边框以编程方式创建的,他们需要在前面填充。 – K1llarney

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方法,并为附加设置和类方法添加一个常用方法来设置文本属性。好处是,如果在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") 
+0

谢谢,我已经实现了你的答案,但仍然有我的OP更新中提到的问题。 – K1llarney