Я создал новый проект OS X в Xcode 8, добавил одно (изображение) представление. Я перетащил его в исходный код ViewController по умолчанию, чтобы добавить @IBOutlet (названный «image»). Затем в viewDidLoad() я добавил:

image.wantsLayer = true
image.layer!.cornerRadius = 10

Примерно в половине случаев он работает нормально, а примерно в половине случаев он умирает с:

fatal error: unexpectedly found nil while unwrapping an Optional value

Указав на вторую строку и в отладчике:

(lldb) po image.wantsLayer
true

(lldb) po image.layer
nil

Предполагается ли, что настройка wantsLayer немедленно создает layer? Документация, кажется, предполагает это, но я не могу найти утверждения, которое бы это явно выражало.

Я видел много кода, >, что заставляет NSView выполнять:

self.wantsLayer = true
self.layer!.backgroundColor = ...

Так что кажется, что это должно быть. Почему после установки wantsLayer значение layer равно нулю? Должен ли я сам устанавливать layer, даже если я прошу wantsLayer?

3
Naha 26 Ноя 2016 в 22:20

2 ответа

Лучший ответ

Для представлений с поддержкой слоев в OS X не рекомендуется напрямую взаимодействовать с объектом слоя. Слой принадлежит AppKit. Здесь это также описано несколькими словами: https : //www.objc.io/issues/14-mac/appkit-for-uikit-developers/

Теперь, если вы подклассифицируете свое представление и вернете YES / true в свойстве wantsUpdateLayer вашего NSView, вы можете обновить слой в updateLayer. Обратите внимание, что это приведет к тому, что AppKit больше не будет вызывать drawRect.

1
Volker 27 Ноя 2016 в 09:00

Для будущих искателей вот код Swift 3 для безопасной установки радиуса угла для изображения (или NSView), создание подклассов не требуется. Доступ к слою напрямую опасен, потому что NSViews не всегда поддерживаются слоями Core Animation. Вместо этого вы можете создать представление размещения слоев и писать в него.

Итак, в viewDidLoad():

let layer = CALayer()
image.layer = layer
image.wantsLayer = true
image.masksToBounds = true
image.cornerRadius = 19
1
teacup 13 Мар 2017 в 23:19