How to conform NSView to CALayerDelegate when you import SwiftUI?

Viewed 418

This compiles:

import AppKit

class CustomView: NSView, CALayerDelegate {
    func layoutSublayers(of layer: CALayer) {}
}

This does not however:

import AppKit
import SwiftUI

class CustomView: NSView, CALayerDelegate {
    func layoutSublayers(of layer: CALayer) {}
}

This is an error:

... error: redundant conformance of 'CustomView' to protocol 'CALayerDelegate'
class CustomView: NSView, CALayerDelegate {}
                          ^
... note: 'CustomView' inherits conformance to protocol 'CALayerDelegate' from superclass here
class CustomView: NSView, CALayerDelegate {}
      ^

Any idea how to fix this?

If you remove CALayerDelegate conformance, delegate methods are not called.

2 Answers

They’re not called because the compiler can’t see they’re implementing the protocol and thus won’t make them available from Objective-C. But you can still make it available manually with the @objc attribute. You should also specify the Objective-C selector name, which isn’t always the same name as in Swift:

import AppKit
import SwiftUI

class CustomView: NSView {
    @objc(layoutSublayersOfLayer:)
    func layoutSublayers(of layer: CALayer) {}
}

The answer by @Michel didn't work for me because I had a different method that was causing the problem.

@objc(drawLayer:inContext:)
func draw(_ layer: CALayer, in ctx: CGContext)
{}

The general solution is still to check the Objective-C method which is implemented in your custom Swift file and use the: @objc(methodName) above the Swift method name.

Here is a list of CALayerDelegate's methods (5):

Swift -> https://developer.apple.com/documentation/quartzcore/calayerdelegate

Objective-C -> https://developer.apple.com/documentation/quartzcore/calayerdelegate?language=objc

Related