跨多个 UIView 子类的单个 drawRect 实现

Posted

技术标签:

【中文标题】跨多个 UIView 子类的单个 drawRect 实现【英文标题】:Single drawRect implementation across multiple UIView subclasses 【发布时间】:2015-09-30 22:31:00 【问题描述】:

在我的应用程序中,我有几个不同的 UIView 子类:UIDatePicker、UIPicker、UIButton、UITableView、UITableViewCell、UITextView 等...对于其中的每一个,我想添加一个非常简单的 drawRect 自定义实现,我工作得很好。

有没有一种简单的方法可以让 UIView 的多个子类都具有相同的 drawRect 实现,而无需创建子类并在每个 UIPicker、UIButton 等之间重复相同的代码......?

我意识到解决这个问题的方法可能是为 UIView 的 layer 属性编写一个委托类并在 drawLayer 中进行自定义绘图,但我想在重新编写代码之前我会问一下。

【问题讨论】:

仅供参考 - 您不应该修改任何自定义 UI 小部件的 drawRect: 方法。 我很好奇您如何为这些不同的 UI 元素使用完全相同的绘图代码。 @rmaddy 我很好奇你的意思。 UIView 及其子类中 drawRect 的自定义实现是 Cocoa/Objective-C 的支柱之一,如果你想添加任何东西到类如何绘制自身。 developer.apple.com/library/ios/documentation/UIKit/Reference/…: 是的,如果不错的话,为您的自己的自定义视图实现drawRect:。但是 Apple 提供的小部件应该是具有私有视图层次结构的黑盒子。您不应该弄乱提供的小部件的绘制方式。 您可以通过 swizzling 在语言级别执行此操作。祖先类中的类别破坏者,除了是一种可怕的、糟糕的、无神论的、可怕的做法之外,将无法工作,因为中间的子类可能有自己的实现。唯一的其他基于语言的选项是您提到的那个:您自己的子类就在您的自定义类之上和最后一个框架类之下,但是我又不确定这实际上是否可行,因为您提到的一些类是@987654324 @s 和其他 UIView 的直系后代。 【参考方案1】:

答案似乎是否定的。

此外,我对解决方法的想法似乎也行不通:我想我可以编写一个不错的小类,从 CALayerDelegate 实现 drawLayer 方法并在其中进行绘图,然后在每个 UIView 或 UIView子类的 init 方法做一个 self.layer.delegate = niceLittleCALayerDelegateClass。

然而,我的研究发生在这件事上:https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CALayer_class/#//apple_ref/occ/instp/CALayer/delegate,其中包含该死的句子:在 iOS 中,如果图层与 UIView 对象相关联,则必须将此属性设置为拥有该图层的视图。

所以,双重不。

根据 rmaddy 的建议,我将只为要在其中实现此绘图行为的每个 UIView 子类编写一个子类。我们将看看它是如何进行的。

更新:

我不敢相信我之前没有想到这一点,但是“正确”的方式来做到这一点(也就是说,没有子类化 UIView 的子类并为每个子类的子类添加自定义的 drawRect 方法),从我的一切可以找到,似乎是创建一个子视图或一个具有透明背景的子层,可以做任何你想要的自定义绘图。

显然,这将在您实际使用的 UIView 之上绘制,因此如果您尝试绘制与 UIView 的默认元素交互的东西,这将变得非常复杂,但出于我的目的(只是一个用 UIBezierPath 绘制的简单框架)它似乎工作得很好。

目前我不确定是 subview 还是 sublayer 方法更有效。如果有人能阐明这一点,我将不胜感激。

【讨论】:

以上是关于跨多个 UIView 子类的单个 drawRect 实现的主要内容,如果未能解决你的问题,请参考以下文章

更新 UIView 子类中 drawRect 中绘制的组件中的文本

UIView 子类:drawRect 未调用

XIB 中的 UIView 子类不显示(drawRect:从未调用)

如果 drawRect: 被覆盖,子类化的 UIView 显示黑色背景

我正在使用 drawRect 实现 UIView 子类:如何绘制按钮?

如何使用 drawRect 覆盖在 UIView 子类的某些区域中获得透明度