Я пытаюсь добавить тень к представлениям, которые наложены друг на друга, представления сворачиваются, позволяя видеть контент в других представлениях, в этом ключе я хочу оставить 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
и сохранить мой контент обрезанным?
Изменить: просто хотел добавить, что я также играл с использованием фоновых изображений с тенями, что действительно хорошо работает, однако я все же хотел бы знать лучшее кодированное решение для этого.
источник
masksToBounds = NO;
к своему оригиналу - с обеими попытками, которые я оставилclipsToBounds = YES;
включенными - обе не смогли обрезать контент. Херес ScreenCap того , что случилось с вашим Пример> youtu.be/tdpemc_XdpsUIBezierPath *shadowPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds cornerRadius:5.0];
. Не тестировался, но должен дать желаемый результат.layoutSubviews()
вызывается. И если мы не компенсируем в этом месте, отрегулировав,shadowPath
чтобы отразить текущий размер, у нас будет вид с измененным размером, но тень все равно будет иметь старый (начальный) размер и либо не будет отображаться, либо смотреть туда, где не должна. .Ответ Васабии в Swift 2.3:
А в Swift 3/4/5:
Поместите этот код в layoutSubviews (), если вы используете AutoLayout.
В SwiftUI все намного проще:
источник
layoutSubviews
CGSize(width: 0, height: 0.5)
view.bounds
он не был создан настолько очевидно, чтоshadowPath
не может ссылаться на прямоугольник представления, а на некоторыеCGRectZero
. В любом случае, этоlayoutSubviews
решило мою проблему!Хитрость заключается в
masksToBounds
правильном определении свойства слоя вашего представления:и он должен работать.
( Источник )
источник
Вы можете создать расширение для UIView для доступа к этим значениям в редакторе дизайна.
источник
Вы также можете установить тень на свой вид из раскадровки
источник
На viewWillLayoutSubviews:
Использование расширения UIView:
Использование:
источник
targetView: UIView
и удалите челку.self
? Мне кажется намного удобнее.if let
синтаксис вместо!
Итак, да, вы должны предпочесть свойство shadowPath для повышения производительности, но также: Из файла заголовка CALayer.shadowPath
Явное указание пути с помощью этого свойства обычно * улучшает производительность рендеринга, так как использование одной и той же ссылки * пути на нескольких уровнях
Менее известный трюк - использовать одну и ту же ссылку на нескольких уровнях. Конечно, они должны использовать одну и ту же форму, но это обычное дело для ячеек представления таблицы / коллекции.
Я не знаю, почему это становится быстрее, если вы делитесь экземплярами, я предполагаю, что он кэширует рендеринг тени и может повторно использовать его для других экземпляров в представлении. Интересно, будет ли это еще быстрее с
источник