【问题标题】:Is the `layer` parameter in `UIView.layoutSublayers(of:)` always the view's layer?`UIView.layoutSublayers(of:)` 中的 `layer` 参数是否总是视图的图层?
【发布时间】:2021-02-20 19:20:32
【问题描述】:

当在 UIView 子类中覆盖 layoutSublayers(of:) 时,我可以安全地假设传递给该方法的层总是是 UIView 的层吗?

如果是这样,这是否在文档中某处进行了说明(我已经搜索但没有找到任何提及)?


为了提供一些关于我为什么要问的上下文:在自定义 UIView 子类中对 CALayerDelegate 方法 layoutSublayers(of:) 的 UIViews 实现的覆盖中,检查该层是否是视图自己的层是否有意义,如下所示:

class FooView: UIView {
    override func layoutSublayers(of layer: CALayer) {
        guard layer === self.layer else { return }
    }
}

或者这个检查是多余的,因为 Apple 官方保证(除非我个人更改它)视图将成为它自己层的代表?

【问题讨论】:

    标签: ios uiview overriding subclass calayer


    【解决方案1】:

    layoutSublayers(of:) 不是 UIView 方法。它是一个 CALayerDelegate 方法,在层的委托上调用。

    好吧,您当然可以保证 UIView 是其 CALayer 的委托,因为这就是 UIView 及其 CALayer 的工作方式。如果不是这样,绘图就会中断,整个界面就会停止工作。

    但是,您不能保证 UIView 不是 一些 other 层的委托!这不会自行发生,但你可以这样设置。但是,您实际上永远不会!在我的书中,我警告不要这样做:

    但要小心! ,在任何情况下,设置一个层的delegate UIView 的底层;并且使 UIView 成为其底层以外的任何层的delegate。 UIView 必须是其底层的委托;此外,它必须是任何其他层的代表。 不要做任何事情来搞砸。如果你这样做,将会发生非常糟糕的事情;例如,绘图将停止正常工作。

    所以是的,您可能想当然地认为所讨论的层是视图的层。

    【讨论】:

    • 我知道这是 CALayerDelegate 需要的方法,但 UIView 确实实现了该方法,因此我可以在自定义子类中覆盖它。很抱歉以一种误解的方式表达我的问题。我可以这样说:“它是否保证 UIView 是 only 它自己的层的代表。感谢您的回答和您书中的引用,文档中是否有苹果官方支持这个观点还是你通过测试得出了这个结论?
    • 另外,虽然它是有道理的,“因为这就是 UIView 及其 CALayer 的工作方式。”对我来说,与官方文档中实际提及的内容不同。
    【解决方案2】:

    上面写着in the official documentation of CALayer:

    如果图层对象是由视图创建的,视图通常会自动将自己指定为图层的代理,您不应更改这种关系。

    “典型地”不是保证,但听起来很可能 UIView 总是它自己的层的委托。不幸的是,没有说明 UIView 是否可以在默认情况下(即在 UIKit 中实现,无需程序员干预)同时也是另一层的委托。

    【讨论】:

    • 不幸的是,没有说明 UIView 是否可以在默认情况下(即在 UIKit 中实现,无需程序员干预)也可以同时成为另一层的委托永远不会。如果您有疑问,请添加条件并检查!但我从 iOS 3 开始就一直这样做,即使你不是,我也确信我的立场。 :)
    • 目前,我总是在添加一个条件(从我的编辑中可以看出)。我问是因为我想知道我是否可以安全地摆脱这种情况。感谢您分享您的经验:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-22
    • 2017-05-15
    • 2012-05-29
    • 2010-11-21
    • 1970-01-01
    相关资源
    最近更新 更多