Что это лучший способ, чтобы добавить тень, чтобы мой наследник UIView
Я пытаюсь добавить тень к представлениям, которые накладываются друг на друга, представления сворачиваются, позволяя видеть контент в других представлениях, в этом ключе я хочу сохранить view.clipsToBounds ВКЛ так, что при сворачивании представлений их содержимое обрезается.
это, кажется, сделало его трудным для меня, чтобы добавить тень к слоям, как когда я поворачиваюсь clipsToBounds на тени также обрезаются.
Я пытался манипулировать view.frame и view.bounds для того чтобы добавить отбросьте тень на кадр, но позвольте границам быть достаточно большими, чтобы охватить его, однако мне не повезло с этим.
вот код, который я использую, чтобы добавить тень (это работает только с clipsToBounds выкл как показано)
view.clipsToBounds = NO;
view.layer.shadowColor = [[UIColor blackColor] CGColor];
view.layer.shadowOffset = CGSizeMake(0,5);
view.layer.shadowOpacity = 0.5;
вот скриншот тени, применяемой к верхнему светлому серому слою. Надеюсь, это дает представление о том, как мой контент будет перекрывать, если clipsToBounds выкл.

как я могу добавить тень к моей UIView и держать мой контент обрезанным?
Edit: просто хотел добавить, что я также играл с использованием фоновых изображений с тенями, что хорошо работает, однако я все равно хотел бы знать лучшее кодированное решение для этого.
6 ответов:
попробуйте это:
UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRect:view.bounds]; view.layer.masksToBounds = NO; view.layer.shadowColor = [UIColor blackColor].CGColor; view.layer.shadowOffset = CGSizeMake(0.0f, 5.0f); view.layer.shadowOpacity = 0.5f; view.layer.shadowPath = shadowPath.CGPath;в первую очередь: The
UIBezierPathиспользовать какshadowPathимеет решающее значение. Если вы не используете его, вы можете не заметить разницу сначала, но острый глаз будет наблюдать определенное отставание, происходящее во время таких событий, как вращение устройства и/или подобное. Это важная настройка производительности.что касается вашего вопроса конкретно: важная строка
view.layer.masksToBounds = NO. Он отключает отсечение слой представления подслои, которые простираются дальше, чем границы этого представления.для тех, кому интересно, в чем разница между
masksToBounds(на слое) и собственный видclipToBoundsсвойство: на самом деле нет. Переключение одного будет иметь эффект на другой. Просто другой уровень абстракции.
Swift 2.2:
override func layoutSubviews() { super.layoutSubviews() let shadowPath = UIBezierPath(rect: bounds) layer.masksToBounds = false layer.shadowColor = UIColor.blackColor().CGColor layer.shadowOffset = CGSizeMake(0.0, 5.0) layer.shadowOpacity = 0.5 layer.shadowPath = shadowPath.CGPath }
Swift 3:
override func layoutSubviews() { super.layoutSubviews() let shadowPath = UIBezierPath(rect: bounds) layer.masksToBounds = false layer.shadowColor = UIColor.black.cgColor layer.shadowOffset = CGSize(width: 0.0, height: 5.0) layer.shadowOpacity = 0.5 layer.shadowPath = shadowPath.cgPath }
ответ Васабии в Swift 2.3:
let shadowPath = UIBezierPath(rect: view.bounds) view.layer.masksToBounds = false view.layer.shadowColor = UIColor.blackColor().CGColor view.layer.shadowOffset = CGSize(width: 0, height: 0.5) view.layer.shadowOpacity = 0.2 view.layer.shadowPath = shadowPath.CGPathи в Swift 3/4:
let shadowPath = UIBezierPath(rect: view.bounds) view.layer.masksToBounds = false view.layer.shadowColor = UIColor.black.cgColor view.layer.shadowOffset = CGSize(width: 0, height: 0.5) view.layer.shadowOpacity = 0.2 view.layer.shadowPath = shadowPath.cgPathпоместите этот код в layoutSubviews (), если вы используете AutoLayout.
трюк заключается в определении
masksToBoundsсвойство слоя вашего представления правильно:view.layer.masksToBounds = NO;и это должно работать.
(источник)
вы можете создать расширение для UIView для доступа к этим значениям в Редакторе дизайна
extension UIView{ @IBInspectable var shadowOffset: CGSize{ get{ return self.layer.shadowOffset } set{ self.layer.shadowOffset = newValue } } @IBInspectable var shadowColor: UIColor{ get{ return UIColor(cgColor: self.layer.shadowColor!) } set{ self.layer.shadowColor = newValue.cgColor } } @IBInspectable var shadowRadius: CGFloat{ get{ return self.layer.shadowRadius } set{ self.layer.shadowRadius = newValue } } @IBInspectable var shadowOpacity: Float{ get{ return self.layer.shadowOpacity } set{ self.layer.shadowOpacity = newValue } } }
на viewWillLayoutSubviews:
override func viewWillLayoutSubviews() { sampleView.layer.masksToBounds = false sampleView.layer.shadowColor = UIColor.darkGrayColor().CGColor; sampleView.layer.shadowOffset = CGSizeMake(2.0, 2.0) sampleView.layer.shadowOpacity = 1.0 }используя расширение UIView:
extension UIView { func addDropShadowToView(targetView:UIView? ){ targetView!.layer.masksToBounds = false targetView!.layer.shadowColor = UIColor.darkGrayColor().CGColor; targetView!.layer.shadowOffset = CGSizeMake(2.0, 2.0) targetView!.layer.shadowOpacity = 1.0 } }использование:
sampleView.addDropShadowToView(sampleView)


Comments