在 Swift 3.1 中为 UIView 子类设置默认外观而不覆盖 initialize()

Posted

技术标签:

【中文标题】在 Swift 3.1 中为 UIView 子类设置默认外观而不覆盖 initialize()【英文标题】:Set default appearance for a UIView subclass without overriding initialize() in Swift 3.1 【发布时间】:2017-03-31 01:44:55 【问题描述】:

我有一个 UITextView 的子类,它需要具有特定的默认外观。到目前为止,我已经能够通过重写在 Swift 3.1 中已弃用的 initialize() 类函数来实现这一点。

public class CustomTextView : UITextView 
    override public class func initialize() 
        self.appearance().backgroundColor = .green
    

有没有办法在纯 Swift 中实现同样的目标?

【问题讨论】:

您可以自定义您的 UITextView 外观,覆盖 didMoveToSuperview 方法。 【参考方案1】:

我正在通过使用这样的构造来解决类方法 initialize 的丢失问题:

class CustomTextView : UITextView 
    override init(frame: CGRect, textContainer: NSTextContainer?) 
        super.init(frame:frame, textContainer: textContainer)
        CustomTextView.doInitialize
    
    required init?(coder aDecoder: NSCoder) 
        super.init(coder:aDecoder)
        CustomTextView.doInitialize
    
    static let doInitialize : Void = 
        CustomTextView.appearance().backgroundColor = .green
    ()

这个构造的优点是doInitialize 只会被初始化一次,因此与之相连的代码只会运行一次(在这种情况下,我们将只配置一次外观代理);甚至影响到创建的第一个实例(也就是说,您创建的每个 CustomTextView 实际上都是绿色的)已经足够早了。

【讨论】:

谢谢。我尝试做类似的事情,但我意识到这需要先实例化类。因此,如果您要先配置自定义外观,然后再实例化该类,则默认外观将覆盖自定义外观。例如: ` CustomTextView.appearance().backgroundColor = .orange;让 t = CustomTextView()`。 t 的背景颜色将是 .green 而不是 .orange。 @DavorBauk 然后你问错了问题。您不会通过设置 appearance 代理来自定义 individual 对象。您可以通过自定义单个对象来自定义该对象。如果这真的是你的目标,Leo Dabus 的回答是对的。 感谢您的反馈。你说得对,我的问题不是要尝试修改单个实例;而是要尝试修改单个实例。那真的只是一个简单的例子。在我的特定场景中,CustomTextField 是在一个共享框架中定义的,该框架被多个应用程序使用。但是,每个应用程序都有一个稍微不同的调色板,所以我想在每个单独的应用程序中进一步自定义 CustomTextField 的外观。例如,在每个应用程序中分别具有不同的默认轮廓颜色,但保持CustomTextView 定义的默认字体和背景颜色。 好的,但您的问题与此无关!你的问题是关于做一些行为类似于initialize 的事情,这就是我的回答。

以上是关于在 Swift 3.1 中为 UIView 子类设置默认外观而不覆盖 initialize()的主要内容,如果未能解决你的问题,请参考以下文章

将 UIView 作为 SubView 添加到自定义类、UIView 的子类、Swift

Swift 子类 UIView

swift 初始化UIView的Swift子类,在.xib中设计

swift 初始化UIView的Swift子类,在.xib中设计

Swift 3:编译器无法识别子类 UIView 的类型

如何在不制作 IBOutlet 的情况下以编程方式在 Swift 中为 UIView 高度约束设置动画?