Ios CATiledLayer如何在内部工作

Ios CATiledLayer如何在内部工作,ios,objective-c,uiview,calayer,catiledlayer,Ios,Objective C,Uiview,Calayer,Catiledlayer,我是iOS开发的新手,我正在尝试弄清楚CATiledLayer是如何工作的。不是怎么用的 CATiledLayer有两个关键特性,我想知道它是如何工作的 可见边界自动报告。CATiledLayer如何知道其可见边界已更改?我可以创建一个自定义CALayer并注册以了解相同的信息吗 瓷砖画。这些瓷砖是怎么画的?它们是否绘制为子图层 我想了解这两个关键点是如何工作的,因为我正在构建一个自定义的UIView,它的宽度非常大,CALayer会因为有这么大的备份层而崩溃CATiledLayer的内存使用量

我是iOS开发的新手,我正在尝试弄清楚
CATiledLayer
是如何工作的。不是怎么用的

CATiledLayer
有两个关键特性,我想知道它是如何工作的

  • 可见边界自动报告。
    CATiledLayer
    如何知道其可见边界已更改?我可以创建一个自定义
    CALayer
    并注册以了解相同的信息吗

  • 瓷砖画。这些瓷砖是怎么画的?它们是否绘制为子图层

  • 我想了解这两个关键点是如何工作的,因为我正在构建一个自定义的
    UIView
    ,它的宽度非常大,
    CALayer
    会因为有这么大的备份层而崩溃
    CATiledLayer
    的内存使用量很小,几乎完美

    我不想使用
    CATiledLayer
    的原因是它的内部工作方式。所有绘图都发生在背景线程上。我知道您甚至可以在主线程上调用绘图逻辑,但这将在下一个绘图周期中发生。由于绘制不是在同一个绘制周期进行的,因此在视图调整大小期间,我们的绘制逻辑会延迟更新图形,从而导致用户在更新期间
    UIView
    内容发生抖动


    只是想再补充一点。我正在构建一个音频编辑器,其中显示音频波形,用户可以调整此剪辑的大小。片段显示在集合视图中。上述有关
    CATiledLayer
    的问题似乎与Garage band的问题相同。当我向左调整音频剪辑的大小时,我几乎没有注意到它。他们可能会使用
    CATiledLayer

    我知道解决第一个问题的方法,但我不确定其后果和效率。这是理论上的,但它是有效的。我正在使用CADisplayLink运行一个检查,以查看层的框架是否在主窗口中。我确实注意到使用了一点CPU(1%或更少),因此与CATiledLayer相比,我会对其进行更多的测试。CATiledLayer只是打断图形,但其操作前提相同,即只能绘制可见的内容。我认为drawRect在可见或可见边界改变时基本上是有效的。就我测试的子类而言,我在UICollectionView中使用了它,并且知道它是有效的。我甚至可以得到一个单元格创建时的日志,而不是在屏幕上。下面是CALayer的工作子类。我不知道这是否对你有帮助,但这是可能的

    import UIKit
    protocol OnScreenLayerDelegate:class {
        func layerIsOnScreen(currentScreenSpace:CGRect)
        func layerIsNotOnScreen(currentScreenSpace:CGRect)
    }
    class OnScreenLayer: CALayer {
    
        var displayLink : CADisplayLink?
        weak var onScreenDelegate : OnScreenLayerDelegate?
        override init() {
            super.init()
            commonSetup()
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            commonSetup()
        }
    
        func commonSetup(){
            displayLink = CADisplayLink(target: self, selector: #selector(checkOnScreen))
            displayLink?.add(to: .main, forMode: .commonModes)
        }
    
        @objc func checkOnScreen(){
            if let window = UIApplication.shared.keyWindow{
                let currentRect = self.convert(self.bounds, to: window.layer)
                if window.bounds.intersects(currentRect){
                    onScreenDelegate?.layerIsOnScreen(currentScreenSpace: currentRect)
                }else{
                    onScreenDelegate?.layerIsNotOnScreen(currentScreenSpace: currentRect)
                }
            }
        }
    }
    
    至于问题2,我认为CATiledLayers可能不使用子层,而是缓慢地将所有内容绘制到单个内容图像中,而是通过平铺和可能更容易的数学运算。它可能是将可见区域绘制在背景中并提供图层内容的东西。然后缓存该部分并添加另一部分,直到完成。这只是猜测

    下面是我在collectionView单元中测试的代码

    import UIKit
    
    class AlbumCollectionViewCell: UICollectionViewCell {
    
        @IBOutlet weak var imageView: UIImageView!
        var onScreenLayer = OnScreenLayer()
        var currentIndex : Int = 0
        override func awakeFromNib() {
            super.awakeFromNib()
            onScreenLayer.frame = self.bounds
            self.layer.addSublayer(onScreenLayer)
            onScreenLayer.onScreenDelegate = self
        }
    
        override func layoutSubviews() {
            super.layoutSubviews()
            onScreenLayer.frame = self.bounds
        }
    }
    
    extension AlbumCollectionViewCell : OnScreenLayerDelegate{
        func layerIsOnScreen(currentScreenSpace: CGRect) {
            //or more proof
             print("it is on screen \(currentIndex)")
    
        }
    
        func layerIsNotOnScreen(currentScreenSpace: CGRect) {
            print("not on screen \(currentIndex)")
        }
    }
    

    当前索引设置在cellForItem中,因此我可以监视它。让我知道这是否有帮助。此外,该检查还可以修改帧,以便在它出现在屏幕上之前,以您在此之前绘制的方式捕捉到它

    有很多信息,但是有没有一种方法可以显示你所建的以及你正在尝试做什么的视频。我在一个我也做过的应用程序中有一个音频波形。@agibson007我之前确实发布过一些关于这个主题的内容,现在我再次要求稍微不同的内容。在这篇文章中,你应该可以看到我得到的一些截图。我也会在这里放一段视频。图形是否会妨碍ui在没有CATiledLayer的情况下一次性绘制它。我把我们的换成了使用一台自动提款机。谢谢你的信息。我有个主意要通知你,所以给我点时间test@agibson007对不起,我对你问题的回答写得很糟糕因此,必须将绘图优化为在collectionview上可见的块,否则较大的音频剪辑会使事情变得非常缓慢。此外,CALayer支持的UIView在太大时崩溃。谢谢你的帮助!使用CADisplayLink是一个有趣的想法。几乎感觉不对,但我将在这里探讨一下你的想法。我会用我找到的任何东西回信。谢谢你花时间帮忙!:)@乔娜,我不反对这种感觉是错误的,只要知道它是有效的