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

CoreGraphics - только смешение * части * вида

Недавно я наткнулся на эту блестящую статью об улучшении производительности прокрутки с помощью UITableViewCells: http://engineering.twitter.com/2012/02/simple-strategies-for-smooth-animation.html - В то время как многие полезные советы можно найти в этом статья, есть, в частности, то, что меня заинтриговало:

В твитах в Twitter для iPhone 4.0 есть тень на фоне тонкого текстурированного фона. Это представляло собой проблему, поскольку смешивание дорого. Мы решили это, уменьшив область, в которой Core Animation должна учитывать непрозрачность, разбивая области тени из области содержимого ячейки.

Используя симулятор iOS, нажав "Отладка - цветные смешанные слои", вы увидите что-то вроде этого:

TwitterTableViewCell

Области, отмеченные красным цветом, смешиваются, а зеленая область непрозрачна. Отлично. В статье не упоминается следующее: Как это реализовать? Я понимаю, что UIView либо непрозрачен, либо нет. Мне кажется, что единственный способ добиться этого - с подзаголовками, но в статье явно указано, что как наивная реализация:

Вместо этого, наши ячейки Tweet содержат одно представление без подзапросов; один drawRect: рисует все.

Итак, как мне отделить то, что непрозрачно, а что нет в моем единственном методе drawRect:??

4b9b3361

Ответ 1

В примере, который вы показываете, я не верю, что они отображают фон через представление. Я думаю, что они имитируют фон в основной графике. Другими словами, в каждой ячейке они рисуют светло-серый цвет для фона. Затем они рисуют тень (используя прозрачность) и, наконец, рисуют остальную часть непрозрачного содержимого сверху. Я могу ошибаться, но я не думаю, что вы можете сделать части зрения прозрачными. Если это так, я был бы очень, очень заинтересован в этом, потому что я использую основную графику все время, но я избегаю округлых углов, потому что смешение всего представления для него просто не похоже на это.

Обновление

Сделав еще несколько исследований и просматривая документы Apple, я не считаю возможным, чтобы только часть представления была непрозрачной. Кроме того, после чтения блога в блоге Twitter, я не думаю, что они говорят, что они это сделали. Обратите внимание, что, когда они говорят:

Вместо этого, наши ячейки Tweet содержат одно представление без подзапросов; один drawRect: рисует все.

Они конкретно говорили о UILabel и UIImageView. Другими словами, вместо использования этих представлений они рисуют изображение напрямую с помощью Core Graphics. Что касается UILabels, я лично использую Core Text, так как у него больше поддержка шрифтов, но они могут также использовать что-то более простое, как метод NSString drawAtPoint:withFont:. Но главное, что они пытаются понять, состоит в том, что содержимое ячейки - это всего один рисунок CG.

Затем они переходят в новый раздел: Избегать смешивания. Здесь они говорят, что избегают смешивания:

разделение теневых областей из области содержимого ячейки.

Единственный способ сделать это - использовать разные представления. Есть два подхода, которые они могли бы использовать, но сначала обратите внимание, что делители ячеек сами являются оверлеями (предоставляемыми tableView). Первый способ - использовать несколько представлений внутри ячейки. Второй способ заключается в том, чтобы наложить/наложить тени/смешанные представления позади/над ячейками, вставив соответствующие представления в UIScrollView. Учитывая их предыдущее утверждение о наличии только одного представления /drawRect для каждой ячейки, это, вероятно, то, что они делают. Каждый метод будет иметь свои проблемы, но лично я думаю, что было бы легче разбить ячейку на 3 вида (тень, контент, тень). Было бы намного легче справляться с ситуациями первой/последней ячейки.

Ответ 2

Мне нужно было что-то угадать в этом направлении http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_shadows/dq_shadows.html

  CGContextRef context = UIGraphicsGetCurrentContext();

UIBezierPath* path = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:10.0f];

CGContextSaveGState(context);
CGRect leftRect = CGRectZero;
CGContextClipToRect(context, leftRect );
CGContextSetBlendMode(context, kCGBlendModeNormal);
// draw shadow

//    Call the function CGContextSetShadow, passing the appropriate values.
//    Perform all the drawing to which you want to apply shadows.
CGContextSetShadowWithColor(context, CGSizeMake(1.0f, 1.0f), 10.0f, [UIColor blackColor].CGColor);
CGContextAddPath(context, path.CGPath);
CGContextDrawPath(context, kCGPathStroke);


CGContextRestoreGState(context);

CGContextSaveGState(context);
CGRect middleSection = CGRectZero;
CGContextClipToRect(context, middleSection);
CGContextSetFillColorWithColor(context, self.backgroundColor.CGColor);
CGContextFillRect(context, self.bounds);
// draw opaque
CGContextSetBlendMode(context, kCGBlendModeCopy); 

CGContextRestoreGState(context);

Ответ 3

Мое мнение таково: не позволяйте Core Animation рисовать тени, используя различные свойства . Просто нарисуйте предварительное изображение с обеих сторон, что на самом деле является тенью. Для изменения переменной высоты ячейки в растяжке ничья может сделать трюк.

EDIT: Если фон прост, то предварительная тень может применяться к обеим сторонам, не зная, что это влияет на визуальную привлекательность.

Если это не применимо, табличное представление должно быть уменьшено до размера без тени. Затем тень можно смешивать, не делая ее для каждой ячейки, а просто "сверху". Это действительно не прокрутка. Это будет работать только в том случае, если тень не имеет никакой "текстуры", иначе можно заметить, что она просто применяется сверху.