С помощью следующего фрагмента я добавляю эффект тени к одному из моих UIView. Что работает очень хорошо. Но как только я установил свойство masksToBounds представления в YES . Эффект падающей тени больше не отображается.
self.myView.layer.shadowColor = [[UIColor blackColor] CGColor];
self.myView.layer.shadowOpacity = 1.0;
self.myView.layer.shadowRadius = 10.0;
self.myView.layer.shadowOffset = CGSizeMake(0.0f, 0.0f);
self.myView.layer.cornerRadius = 5.0;
self.myView.layer.masksToBounds = YES; // <-- This is causing the Drop shadow to not be rendered
UIBezierPath *path = [UIBezierPath bezierPathWithCurvedShadowForRect:self.myView.bounds];
self.myView.layer.shadowPath = path.CGPath;
self.myView.layer.shouldRasterize = YES;
У вас есть идеи по этому поводу?
ios
objective-c
uiview
calayer
jchatard
источник
источник
Сейчас iOS 6, возможно, все изменилось. Ответ TheSquad не работает для меня, пока мне не удалось добавить еще одну строку
view2.layer.masksToBounds = NO;
, иначе тень не отображается. Хотя в документации указано «masksToBounds
НЕТ» по умолчанию, мой код показывает обратное.Вот как я делаю кнопку с закругленным углом с тенью, которая является одним из наиболее часто используемых фрагментов кода в моем приложении.
button.layer.masksToBounds = YES; button.layer.cornerRadius = 10.0f; view.layer.masksToBounds = NO; // critical to add this line view.layer.cornerRadius = 10.0f; view.layer.shadowOpacity = 1.0f; // set shadow path to prevent horrible performance view.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:_button.bounds cornerRadius:10.0f].CGPath; [view addSubview:button];
РЕДАКТИРОВАТЬ
Если просмотры нужно анимировать или прокручивать, это
masksToBounds = YES
значительно снизит производительность, а это означает, что анимация, вероятно, будет зависать. Чтобы получить закругленный угол и тень, а также плавную анимацию или прокрутку, используйте вместо этого следующий код:button.backgroundColor = [UIColor clearColor]; button.layer.backgroundColor = [UIColor redColor].CGColor; button.layer.masksToBounds = NO; button.layer.cornerRadius = 10.0f; view.layer.shadowOpacity = 0.5f; view.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:_button.bounds cornerRadius:10.0f].CGPath; view.layer.shadowOffset = CGSizeMake(0.0f, 4.0f); view.layer.shadowRadius = 2.0f; view.layer.masksToBounds = NO; view.layer.cornerRadius = 10.0f; [view addSubview:button];
источник
Это Swift 3 и IBDesignable версия ответа, опубликованная @TheSquad.
Я использовал ту же концепцию при внесении изменений в файл раскадровки. Сначала я переместил свой targetView (тот, который требует углового радиуса и тени) внутрь нового containerView . Затем я добавил следующие строки кода (Ссылка: https://stackoverflow.com/a/35372901/419192 ), чтобы добавить некоторые атрибуты IBDesignable для класса UIView:
@IBDesignable extension UIView { /* The color of the shadow. Defaults to opaque black. Colors created * from patterns are currently NOT supported. Animatable. */ @IBInspectable var shadowColor: UIColor? { set { layer.shadowColor = newValue!.cgColor } get { if let color = layer.shadowColor { return UIColor(cgColor: color) } else { return nil } } } /* The opacity of the shadow. Defaults to 0. Specifying a value outside the * [0,1] range will give undefined results. Animatable. */ @IBInspectable var shadowOpacity: Float { set { layer.shadowOpacity = newValue } get { return layer.shadowOpacity } } /* The shadow offset. Defaults to (0, -3). Animatable. */ @IBInspectable var shadowOffset: CGPoint { set { layer.shadowOffset = CGSize(width: newValue.x, height: newValue.y) } get { return CGPoint(x: layer.shadowOffset.width, y:layer.shadowOffset.height) } } /* The blur radius used to create the shadow. Defaults to 3. Animatable. */ @IBInspectable var shadowRadius: CGFloat { set { layer.shadowRadius = newValue } get { return layer.shadowRadius } } /* The corner radius of the view. */ @IBInspectable var cornerRadius: CGFloat { set { layer.cornerRadius = newValue } get { return layer.cornerRadius } }
После добавления этого кода я вернулся к раскадровке и, выбрав свой containerView, теперь смог найти новый набор атрибутов в инспекторе атрибутов:
Помимо добавления значений для этих атрибутов по моему выбору, я также добавил радиус угла в свой targetView и установил для свойства masksToBounds значение true.
Надеюсь, это поможет :)
источник
Версия Swift 3.0 с StoryBoard
Та же идея с @TheSquad. Создайте новый вид под фактическим видом и добавьте тень к нижнему виду.
1. Создайте представление под фактическим представлением.
Перетащите
UIView
на StoryBoard с тем же ограничением, что и в целевом представлении. Отметьте клип для привязки к целевому виду. Также убедитесь, что новое представление указано перед целевым представлением, чтобы целевое представление перекрывало новое представление.2. Теперь свяжите новое представление с вашим кодом, добавьте тень на него.
Это всего лишь образец. Вы можете делать здесь все, что хотите
shadowView.layer.masksToBounds = false shadowView.layer.shadowColor = UIColor.red.cgColor shadowView.layer.shadowOpacity = 0.5 shadowView.layer.shadowOffset = CGSize(width: -1, height: 1) shadowView.layer.shadowRadius = 3 shadowView.layer.shadowPath = UIBezierPath(rect: coverImage.bounds).cgPath shadowView.layer.shouldRasterize = true
источник
У меня также были серьезные проблемы с производительностью с тенями и закругленными углами. Вместо использования части shadowPath я использовал следующие строки, которые отлично решили проблему производительности:
self.layer.shouldRasterize = YES; self.layer.rasterizationScale = UIScreen.mainScreen.scale;
источник
Вот одно из решений:
@IBOutlet private weak var blockView: UIView! { didSet { blockView.backgroundColor = UIColor.white blockView.layer.shadowColor = UIColor.black.cgColor blockView.layer.shadowOpacity = 0.5 blockView.layer.shadowOffset = CGSize.zero blockView.layer.cornerRadius = 10 } } @IBOutlet private weak var imageView: UIImageView! { didSet { imageView.layer.cornerRadius = 10 imageView.layer.masksToBounds = true imageView.layer.shouldRasterize = true } }
источник