Подтвердить что ты не робот

Самый быстрый способ сделать тени на iOS?

QuartzCore.layer.shadow высасывает производительность. Кажется, что их нужно переделать каждый раз, когда что-то меняется, что приводит к задержке.

Градиент Coregraphics (для односторонних теней) - не выглядит правильным. если ваш градиент идет от 0,3 альфа до 0, он имеет некоторый нечетный эффект, когда вы можете "видеть" его остановку. Это просто не выглядит красивым или естественным. Может быть, это не затухает, но я уверен, что слышал основные графические градиенты. Это странно, я не знаю.

Тень Coregraphics - требуется некоторое время для рендеринга при их установке, но в остальном отличная производительность. Это только вторая секунда, когда вы ожидаете появления представления, потому что она должна сначала сделать ее тень, что проблема.

Поэтому я должен что-то упустить. Есть ли другой метод, который выглядит правильно и быстро и рентабельно, и в производительности?

4b9b3361

Ответ 1

Добавление shadowPath должно дать вам огромный прирост производительности. В следующем примере предполагается, что вам нужна только тень по сторонам вашего представления

CGPathRef path = [UIBezierPath bezierPathWithRect:view.bounds].CGPath;
[view.layer setShadowPath:path];

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

self.view.layer.shouldRasterize = YES;
// Don't forget the rasterization scale
// I spent days trying to figure out why retina display assets weren't working as expected
self.view.layer.rasterizationScale = [UIScreen mainScreen].scale;

Ответ 2

Я часто видел людей, использующих ОГРОМНЫЙ уровень представления влияния производительности, чтобы создать округленный угол или dropshadow. Что-то вроде этого:

[v.layer setCornerRadius:30.0f];
[v.layer setBorderColor:[UIColor lightGrayColor].CGColor];
[v.layer setBorderWidth:1.5f];
[v.layer setShadowColor:[UIColor blackColor].CGColor];
[v.layer setShadowOpacity:0.8];
[v.layer setShadowRadius:3.0];
[v.layer setShadowOffset:CGSizeMake(2.0, 2.0)];
.....

У этого есть влияние ОГРОМНОЕ, особенно с тенью. Включение таких представлений в UITableView (или что-то, что движется), приведет к созданию прокрутки android-ish, вам этого не нужно. Если вам нужно одушевить или переместить вид, не создавайте закругленные углы и не отбрасывайте тени таким образом!

Знакомьтесь с основной графикой
Я создал простой подкласс UIView, чтобы показать вам, как добиться того же результата несколько иначе. Он использует Core Graphics для рисования представления и в отличие от вышеприведенного кода, это не влияет на производительность.

Здесь код чертежа:

- (void)drawRect:(CGRect)rect
{
   CGContextRef ref = UIGraphicsGetCurrentContext();

  /* We can only draw inside our view, so we need to inset the actual 'rounded content' */
  CGRect contentRect = CGRectInset(rect, _shadowRadius, _shadowRadius);

  /* Create the rounded path and fill it */
  UIBezierPath *roundedPath = [UIBezierPath bezierPathWithRoundedRect:contentRect cornerRadius:_cornerRadius];
  CGContextSetFillColorWithColor(ref, _fillColor.CGColor);
  CGContextSetShadowWithColor(ref, CGSizeMake(0.0, 0.0), _shadowRadius, _shadowColor.CGColor);
  [roundedPath fill];

  /* Draw a subtle white line at the top of the view */
  [roundedPath addClip];
  CGContextSetStrokeColorWithColor(ref, [UIColor colorWithWhite:1.0 alpha:0.6].CGColor);
  CGContextSetBlendMode(ref, kCGBlendModeOverlay);

  CGContextMoveToPoint(ref, CGRectGetMinX(contentRect), CGRectGetMinY(contentRect)+0.5);
  CGContextAddLineToPoint(ref, CGRectGetMaxX(contentRect),   CGRectGetMinY(contentRect)+0.5);
  CGContextStrokePath(ref);
 }

Смотрите этот блог: http://damir.me/rounded-uiview-with-shadow-the-right-way