2017-07-28 64 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