CATiledLayer doesn't work as expected on macOS.
It's choosing to render too few tiles.
In my example, my view is 300px wide. I set layer's transform scale to 4x.
In that case, CATiledLayer renders only two tiles: 50px wide at 2x scale, and stretches them.
Interestingly, when I run similar code on iOS, it works correctly - it renders 3 tiles, 25px wide at 4x scale.
Is it a bug or am I missing something here?
My code below:
It's choosing to render too few tiles.
In my example, my view is 300px wide. I set layer's transform scale to 4x.
In that case, CATiledLayer renders only two tiles: 50px wide at 2x scale, and stretches them.
Interestingly, when I run similar code on iOS, it works correctly - it renders 3 tiles, 25px wide at 4x scale.
Is it a bug or am I missing something here?
My code below:
Code Block swift class WaveformView: NSView { var scale: CGFloat = 1.0 { didSet { layer?.transform = CATransform3DScale(CATransform3DIdentity, scale, 1.0, 1.0) layer?.setNeedsDisplay(bounds) } } private var tiledLayer: CATiledLayer { layer as! CATiledLayer } override init(frame frameRect: NSRect) { super.init(frame: frameRect) wantsLayer = true tiledLayer.levelsOfDetail = 8 tiledLayer.levelsOfDetailBias = 8 tiledLayer.tileSize = CGSize(width: 100.0, height: .infinity) tiledLayer.contentsScale = 1.0 } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func draw(_ dirtyRect: NSRect) { let nsContext = NSGraphicsContext.current! let cgContext = nsContext.cgContext cgContext.saveGState() let scaleX: CGFloat = cgContext.ctm.a NSColor.red.setStroke() NSBezierPath(rect: dirtyRect) .stroke() let fontSize: CGFloat = 12.0 let attr = [ NSAttributedString.Key.font: NSFont.systemFont(ofSize: fontSize) ] let str = "S: \(scaleX)\n\(dirtyRect.width)" as NSString str.draw(at: NSPoint(x: dirtyRect.minX, y: dirtyRect.midY), withAttributes: attr) nsContext.cgContext.restoreGState() } override func makeBackingLayer() -> CALayer { return CATiledLayer() } }