【发布时间】:2019-07-16 12:50:41
【问题描述】:
我有一个正在尝试解决的继承问题。通常,我在这里只使用多重继承,但 Swift 并没有真正做到这一点。
自定义 UIView
import UIKit
class ValidationView: UIView {
var required:Bool = false
var validRegex:String? = nil
var requiredLbl:UILabel?
private var requiredColor:UIColor = UIColor.red
private var requiredText:String = "*"
private var requiredFont:UIFont = UIFont.systemFont(ofSize: 16.0, weight: UIFont.Weight.bold)
override init(frame: CGRect) {
super.init(frame: frame)
self.setupValidationViews()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setupValidationViews()
}
private func setupValidationViews() {
self.requiredLbl = UILabel(frame: CGRect(x: self.frame.width - 30, y: 30, width: 20, height: 20))
self.styleRequiredLabel()
self.addSubview(self.requiredLbl!)
}
func styleRequiredLabel(color:UIColor?, text:String?, font:UIFont?) {
self.requiredColor = color ?? self.requiredColor
self.requiredText = text ?? self.requiredText
self.requiredFont = font ?? self.requiredFont
self.styleRequiredLabel()
}
private func styleRequiredLabel() {
self.requiredLbl?.textColor = self.requiredColor
self.requiredLbl?.text = self.requiredText
self.requiredLbl?.font = self.requiredFont
}
}
自定义 UITextField
import Foundation
import UIKit
@IBDesignable open class CustomTextField: UITextField {
@IBInspectable public var borderWidth: CGFloat = 2.0 {
didSet {
layer.borderWidth = borderWidth
}
}
@IBInspectable public var borderColor: UIColor = UIColor.lightGray {
didSet {
layer.borderColor = borderColor.cgColor
}
}
@IBInspectable public var cornerRadius: CGFloat = 4.0 {
didSet {
layer.cornerRadius = cornerRadius
layer.masksToBounds = true
}
}
}
我希望自定义 UITextField 也成为 ValidationView。我知道我可以做一个协议和扩展,然后让我的 CustomTextField 实现该协议,但这不允许初始化覆盖。我宁愿不必更改实现 ValidationView 的视图的 inits。
这样的事情可以使用@arturdev 回答来完成。我最终得到了这个:
import UIKit
class ValidatableProperties {
var required:Bool
var validRegex:String?
var requiredColor:UIColor
var requiredText:String
var requiredFont:UIFont
init(required:Bool, validRegex:String?, requiredColor:UIColor, requiredText:String, requiredFont:UIFont) {
self.required = required
self.validRegex = validRegex
self.requiredText = requiredText
self.requiredColor = requiredColor
self.requiredFont = requiredFont
}
}
protocol Validatable : UIView {
var validatableProperties:ValidatableProperties! { get set }
var requiredLbl:UILabel! { get set }
func setupValidationDefaults()
func setupValidationViews(frame:CGRect)
func styleRequiredLabel(color:UIColor?, text:String?, font:UIFont?)
}
extension Validatable {
func setupValidationDefaults() {
let props = ValidatableProperties(required: false, validRegex: nil, requiredColor: UIColor.red, requiredText: "*", requiredFont: UIFont.systemFont(ofSize: 16.0, weight: .bold))
self.validatableProperties = props
}
func setupValidationViews(frame:CGRect) {
self.requiredLbl = UILabel(frame: CGRect(x: frame.width, y: 0, width: 20, height: 20))
self.styleRequiredLabel()
self.addSubview(self.requiredLbl)
}
func styleRequiredLabel(color:UIColor?, text:String?, font:UIFont?) {
self.validatableProperties.requiredColor = color ?? self.validatableProperties.requiredColor
self.validatableProperties.requiredText = text ?? self.validatableProperties.requiredText
self.validatableProperties.requiredFont = font ?? self.validatableProperties.requiredFont
self.styleRequiredLabel()
}
private func styleRequiredLabel() {
self.requiredLbl.textColor = self.validatableProperties.requiredColor
self.requiredLbl.text = self.validatableProperties.requiredText
self.requiredLbl.font = self.validatableProperties.requiredFont
}
}
open class ValidationTextField:UITextField, Validatable {
var requiredLbl: UILabel!
var validatableProperties: ValidatableProperties!
override public init(frame: CGRect) {
super.init(frame: frame)
self.setupValidationDefaults()
self.setupValidationViews(frame: frame)
}
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setupValidationDefaults()
self.setupValidationViews(frame: self.frame)
}
}
但这需要将您希望验证的所有类扩展为它们自己的自定义类,每次都需要覆盖 inits 并调用方法。它可以工作,但并不理想,虽然不完全是反模式继承,但肯定有一些代码味道。
【问题讨论】:
标签: swift inheritance uiview