Несколько теневых теней на одном экране iOS
Я ищу, чтобы добавить несколько теней теней с различными непрозрачностью в представление. Спецификации для теней следующие:
- Y-смещение 4 с радиусом размытия 1
- Y-смещение 10 с радиусом размытия 10
- Y-смещение 2 с радиусом размытия 4
- Радиус размытия 1, распространение 1 (без смещений, вероятно, должно быть 4 разных тени)
Я могу полностью справиться с этим, используя CALayer
s. Вот код, на котором я работаю для этого (обратите внимание, что я еще не потрудился установить shadowPath
и не буду, пока не получу работу нескольких теней):
layer.cornerRadius = 4
layer.masksToBounds = false
layer.shouldRasterize = true
let layer2 = CALayer(layer: layer), layer3 = CALayer(layer: layer), layer4 = CALayer(layer: layer)
layer.shadowOffset = CGSizeMake(0, 4)
layer.shadowRadius = 1
layer2.shadowOffset = CGSizeMake(0, 10)
layer2.shadowRadius = 10
layer2.shadowColor = UIColor.blackColor().CGColor
layer2.shouldRasterize = true //Evidently not copied during initialization from self.layer
layer3.shadowOffset = CGSizeMake(0, 2)
layer3.shadowRadius = 4
layer3.shouldRasterize = true
layer4.shadowOffset = CGSizeMake(0, 1)
layer4.shadowRadius = 1
layer4.shadowOpacity = 0.1
layer4.shouldRasterize = true
layer.addSublayer(layer2)
layer.addSublayer(layer3)
layer.addSublayer(layer4)
(Хотя этот код находится в Swift, я считаю, что он выглядит достаточно знакомым для большинства разработчиков Cocoa/Objective-C, чтобы он имел смысл. Просто знайте, что layer
эквивалентен self.layer
в этом контексте. )
Проблема, однако, возникает, когда я пытаюсь использовать разные непрозрачности для каждой тени. Свойство shadowOpacity
layer
заканчивается тем, что применяется ко всем его подслоям. Это проблема, поскольку мне нужно, чтобы все они обладали собственной непрозрачностью. Я попытался установить непрозрачность теневого слоя на его правильное значение (0.04
, 0.12
и т.д.), Но затем непрозрачность 0.04
of layer
применяется ко всем подслоям. Поэтому я попытался установить layer.shadowOpacity
на 1.0
, но это сделало все тени сплошными черными. Я также старался быть умным и делать layer2.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.12).CGColor
, но он был просто изменен на полный черный, без прозрачности.
Я предполагаю, что это имеет какой-то смысл, что слои должны иметь ту же непрозрачность теней. Но какой способ получить эту работу, различную непрозрачность и все (не нужно использовать CALayer
, если это проще другим способом)?
Пожалуйста, не отвечайте "просто используйте изображение" : как бы ни было разумно, я стараюсь избегать этого. Просто пошутите меня.
Спасибо.
EDIT: согласно запросу, вот что мне нужно:
.
Ответы
Ответ 1
Ключевым моментом, который нужно добавить, является установка слоев shadowPath
. По умолчанию Core Graphics рисует тень вокруг видимого содержимого слоя, но в вашем коде не установлены ни backgroundColor
, ни bounds
для слоев, поэтому слои фактически пусты.
Предполагая, что у вас есть подкласс UIView, вы можете заставить его работать, добавив что-то вроде этого:
override func layoutSubviews() {
super.layoutSubviews()
layer.sublayers?.forEach { (sublayer) in
sublayer.shadowPath = UIBezierPath(rect: bounds).cgPath
}
}
Я тестировал этот подход при просмотре с несколькими тенями, и он работал как ожидалось, как только shadowPath
определен для теневых слоев. Различные теневые цвета и непрозрачность работали, но вы должны помнить, что верхние слои в иерархии будут перекрывать слои позади них, поэтому, если передний слой имеет толстую тень, другие тени могут быть скрыты им.
Ответ 2
Как насчет добавления альфа-канала к цвету тени вместо непрозрачности слоя?
т.е. вместо
layer.shadowColor = UIColor.black.cgColor
layer.shadowOpacity = 0.5
делать
layer.shadowColor = UIColor.black.withAlphaComponent(0.5).cgColor
для каждого слоя.