Swift-代码重用
我想要一些关于代码重用的建议 我有一个视图控制器,在这个阶段有12个标签和12个文本字段 对于每个标签和字段,都有重复的代码行(请参见下面的注释行) 我想知道在创建标签和文本字段时重用代码行的最佳方法,而不必一直重写它们Swift-代码重用,swift,uitextfield,uilabel,Swift,Uitextfield,Uilabel,我想要一些关于代码重用的建议 我有一个视图控制器,在这个阶段有12个标签和12个文本字段 对于每个标签和字段,都有重复的代码行(请参见下面的注释行) 我想知道在创建标签和文本字段时重用代码行的最佳方法,而不必一直重写它们 我研究了扩展,创建了一个类,还对公共代码行进行了子类化,但我一直在碰壁 我已经使用了一个类来填充文本字段,并且理解了它是如何工作的,但是我似乎无法将其他公共属性添加到该类中。谢谢 例如: let LabelA = UILabel() // LabelA.backgroundCo
我研究了扩展,创建了一个类,还对公共代码行进行了子类化,但我一直在碰壁 我已经使用了一个类来填充文本字段,并且理解了它是如何工作的,但是我似乎无法将其他公共属性添加到该类中。谢谢 例如:
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“
**更新**
谢谢你的评论
我现在通过在padding类中添加func来重新使用公共代码行
不幸的是,文本字段填充不再有效
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
我不确定我有什么地方错了/不明白。谢谢。创建具有这些重复属性的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
}
这里的示例是一个类func,您需要将其称为静态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...")
func mkInput(with text: String) -> (UILabel, UITextField) {
let label: UILabel
let textField: UITextField
// config these as you want...
return (label, textField)
}
在这种情况下,我会使用stackview(这里有一个很好的例子),所以你不必一直为填充物等而烦恼 您可以创建如下函数:
let textFieldA = PaddedTextField(with: "placeholder text...")
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) }
等等。:) 简单解决方案是将文本字符串作为参数传递并返回标签的函数:
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属性的class方法。好处是,如果文本字段是在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")
“对常见代码行进行子类化,但我总是碰壁”。墙是什么?@Lawliet我一直碰到的墙是添加func,但没有得到我期望的结果。根据我对OP的更新。谢谢,我已经实现了你的答案,但仍然有我OP更新中提到的问题。谢谢你的输入。供参考…我在设置标签后以及之后使用堆栈视图我设置了文本字段。我正在使用填充,因为这些字段是通过编程方式创建的,带有边框,它们需要在前面填充。谢谢,我已经实现了你答案的一部分,我将进一步了解“工厂的”。@K1llarney刚刚更新了我的答案,请查看一下。谢谢你,零,你是冠军。