I made a new OS X project in Xcode 8, added a single (image) view. I dragged it to the default ViewController source, to add an @IBOutlet (named "image"). Then in viewDidLoad()
, I added:
image.wantsLayer = true
image.layer!.cornerRadius = 10
About half the time, it works fine, and about half the time, it dies with:
fatal error: unexpectedly found nil while unwrapping an Optional value
while pointing at the second line, and in the debugger:
(lldb) po image.wantsLayer
true
(lldb) po image.layer
nil
Is setting wantsLayer
supposed to create a layer
immediately? The documentation seems to suggest this, but I can't find a statement that makes this explicit.
I've seen a lot of code, like this, which makes an NSView do:
self.wantsLayer = true
self.layer!.backgroundColor = ...
so it seems like it ought to. Why would layer
be nil, after setting wantsLayer
? Am I supposed to set layer
myself, even if I ask for wantsLayer
?
For layer backed views on OS X it is not recommended to interact with the layer object directly. The layer is owned by AppKit. That is described in a few more words here as well: https://www.objc.io/issues/14-mac/appkit-for-uikit-developers/
Now, if you subclass your view and return YES/true on wantsUpdateLayer
property of your NSView
, you can update the layer in updateLayer
. Note this will lead to AppKit not calling drawRect
anymore.