Не могут добавить угловой радиус и тень

Я пытаюсь потянуть тень и угловой радиус на изображении. Я могу добавить их отдельно, но у меня нет способа добавить оба эффекта одновременно. Я добавляю тень с:

[layer setShadowOffset:CGSizeMake(0, 3)];
[layer setShadowOpacity:0.4];
[layer setShadowRadius:3.0f];
[layer setShouldRasterize:YES];

Здесь, слой является CALayer подкласса UIView. Таким образом, это работает каждый раз, когда я установил

[layer setMasksToBounds:NO];

Теперь для добавления углового радиуса я делаю это:

[layer setCornerRadius:7.0f];

но я должен установить MasksToBounds на ДА для этого для работы:

[layer setMasksToBounds:YES];

Есть ли так или иначе, я могу получить оба из этих эффектов добавить?

Спасибо за внимание,

Denis

33
задан Peter Hosey 23 July 2010 в 08:52
поделиться

1 ответ

Да, да, есть...

Если вам нужен и радиус угла, и падающая тень, вы не включаете -masksToBounds, а задаете радиус угла и задаете контур безье для тени с закругленным прямоугольником. Радиус обоих прямоугольников должен быть одинаковым:

[layer setShadowOffset:CGSizeMake(0, 3)];
[layer setShadowOpacity:0.4];
[layer setShadowRadius:3.0f];
[layer setShouldRasterize:YES];

[layer setCornerRadius:12.0f];
[layer setShadowPath:
                   [[UIBezierPath bezierPathWithRoundedRect:[self bounds]
                                               cornerRadius:12.0f] CGPath]];

Возможно, вы захотите проверить производительность без параметра -shouldRasterize, установленного после задания контура тени. Производительность рисования, как правило, очень хорошая после установки пути тени.

ОБНОВЛЕНИЕ

Я не рассматривал эту проблему довольно давно, но, похоже, больше не нужно устанавливать shadowPath для того, чтобы это работало. Теперь достаточно установить angleRadius и shadowOpacity. Думаю, так было со времен iOS5 (насколько я могу судить). Предоставление этого обновления, вероятно, излишне, поскольку установка этих параметров "просто работает", но я приведу его для потомков. Вкратце, теперь это все, что вам нужно:

[layer setShadowOpacity:0.4];
[layer setCornerRadius:12.0f];

Если вам все еще нужна лучшая производительность, вы можете пойти дальше и установить параметр shouldRasterize также:

[layer setShouldRasterize:YES];

И говоря о производительности, стоит отметить, что если вы замечаете вялую анимацию, вы захотите использовать технику установки пути тени. Это обновление было просто для того, чтобы указать, что установка пути больше не требуется для достижения эффекта одновременного отображения радиуса угла и тени. Однако если производительность является вашим приоритетом, используйте путь.

UPDATE 2

Поскольку люди, похоже, испытывают трудности с тем, чтобы заставить это работать в некоторых случаях, я опубликую здесь более полный фрагмент кода из примера проекта, который я создал:

- (void)viewDidLoad
{
  [super viewDidLoad];

  CALayer *layer = [CALayer layer];
  [layer setBounds:CGRectMake(0.0f, 0.0f, 100.0f, 200.0f)];
  [layer setPosition:[[self view] center]];
  [layer setBackgroundColor:[[UIColor lightGrayColor] CGColor]];
  [layer setShadowOpacity:0.55f];
  [layer setCornerRadius:8.0f];
  [layer setBorderWidth:1.0f];

  [[[self view] layer] addSublayer:layer];

  [[[self testView] layer] setShadowOpacity:0.55f];
  [[[self testView] layer] setShadowRadius:15.0f];
  [[[self testView] layer] setCornerRadius:8.0f];
  [[[self testView] layer] setBorderWidth:1.0f];
}

testView - это UIView, который я добавил в Interface Builder и установил аутлет. Это нужно для того, чтобы убедиться, что он работает одинаково на обоих слоях, которые вы добавляете явно, а также на слоях внутри вложенных представлений.

Я проверил это на симуляторах для iOS5 и iOS6.1. В каждом из них я получил такой результат:

enter image description here

59
ответ дан 27 November 2019 в 18:10
поделиться