Как я могу добавить тень к сгруппированному UITableView (как видно из официального приложения Twitter)? - PullRequest
28 голосов
/ 25 декабря 2011

У меня есть стандартное сгруппированное представление таблицы. Я хотел бы добавить тень вокруг него (т. Е. По краю каждого раздела таблицы) - если вы не уверены, что я имею в виду, посмотрите в официальном приложении Twitter (ниже) для примера. Это довольно тонко, но это определенно тень в отличие от границы.

Twitter app

Как мне добиться этого эффекта?

Сохранение для использования изображений со встроенными тенями в качестве фона каждой ячейки - что не позволит изменять размер анимированной ячейки так, как мне нужно - я не нашел выхода.

Ответы [ 5 ]

25 голосов
/ 01 января 2012

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

Решение 1 (сложное решение): Я думаю, что это решение может сработать, если вы анимируете cornerRadius или не уверены в точной форме сечения.клеток.Вы пробовали использовать shadowPath, как предлагает Ecarrion, но применяли его к своей пользовательской ячейке UITableView?Представьте себе путь для центральных ячеек (не сверху и снизу), который немного шире, чем ячейка на оси x, и короче на оси y.

Затем необходимо убедиться, что тень отбрасывается наверх и низ секции, не перекрывая каждую отдельную тень, верно?Таким образом, для верхней и нижней ячеек вы увеличиваете shadowPath по оси Y, скажем, на 4 пункта больше.Затем вы настраиваете свойство shadowOffset для этих ячеек, также на 4 точки по оси Y.Если shadowOffset центральной ячейки (0,0), то верхняя ячейка (0, -4), а нижняя ячейка (0,4).

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

РЕДАКТИРОВАТЬ: Выходя за рамки использования shadowPath, вы можете сделать составную ячейку для табличного вида с прозрачным фоновым слоем немного меньшим теневым слоем и еще меньшим слоем для добавления текста.и изображения.Слой тени основан на слое текста / изображения, может быть немного шире, выше, короче и т. Д. Примените размытие к этому слою, а затем замаскируйте его прямоугольной маской так, чтобы там, где заканчивается один слой тени, начинался следующий.С верхним и нижним слоями маска должна проходить вверх или вниз до самой высокой / самой низкой точки на оси y, на которой появляется эффект тени (вам все равно придется маскировать сторону, примыкающую к следующей ячейке).Это зависит от того, насколько далеко вы готовы пойти для достижения точного эффекта ... может быть, это даст вам больше боеприпасов.

Решение 2 (несколько более простое решение): Если выточно знать, каким будет значение cornerRadius в верхней и нижней ячейках, и единственное, что вы не обязательно знаете, это длину и / или ширину ячеек, вы можете использовать старый трюк «растянутый однопиксельный графический».

Сначала вы Photoshop / Gimp изображение для угловой тени.Если ширина всегда одинакова, это изображение может быть тенью для всей вершины ячейки.Это же изображение можно использовать для других углов или нижней части ячейки, повернув его.

Теперь хитрость.Возьмите 1 x 5 часть эффекта размытия или градиента, который вы использовали для угловой тени.Если ваш теневой эффект составляет 3 пикселя, сделайте это 1x3 и т. Д. Экспортируйте в PNG или предпочтительный формат и убедитесь, что, если вы поместите его край к краю углового изображения, он выравнивается ровно (размытие или градиент имеют те же значения цвета безвидимый шов).

Все ячейки получают слой рядом с видимой частью ячейки (слева и справа) с вашим изображением 1x5 в качестве содержимого слоя.Также может быть растянутый UIImageView, ваш выбор.Эти линии составляют левую и правую тени.

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

Хорошо, изображение говорит тысячу слов, так как мне кажется,чтобы толкнуть столько слов, вот изображение для иллюстрации:

stretching a 1px image for a scalable border or shadow effect

12 голосов
/ 11 ноября 2012

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

https://github.com/schluete/GroupedTableViewWithShadows

Эффект реализован в категории UITableViewCell UITableViewCell + CellShadows.m .

Первый шаг - создать теневой прямоугольник. Увеличьте прямоугольник в зависимости от положения ячейки в сечении (верх, середина, низ), чтобы закругленные углы не были видны в неправильных углах (строки 18-23). Затем добавьте тень на фоновый вид ячейки (строки 35-41).

Теперь есть хороший эффект тени, но тень первой ячейки "перетекает" во вторую ячейку. Чтобы предотвратить кровотечение, просто добавьте маску слоя, чтобы отрезать все ненужные части тени (строки 25-32 и 43-46). Вот и все, у нас есть наша тень!

2 голосов
/ 26 декабря 2011

На самом деле вы можете попытаться использовать обычный вид tableView (не сгруппированный) и создать 2 (или более) вида ячеек с определенным идентификатором для каждого. Один для верхнего с верхней / левой / правой тенью, один для последнего с левой / правой / нижней тенью и один для других ячеек с левой / правой тенью. В вашем tableView: cellForRowAtIndexPath: просто проверьте, в какой строке вы находитесь (например, indexPath.row == 0), и верните правильную ячейку.

0 голосов
/ 01 мая 2014

Рискуя поднять старый вопрос, я чувствую, что ни один из предоставленных ответов не привел ни к каким приличным практикам кодирования, и при этом они не "чисты и просты".

Я обнаружил, что к этому подходу чище. Посмотрите, что вы думаете. Во-первых, вам нужно будет создать подкласс UITableViewCell. Затем, либо в заголовке, либо в другом месте, сделайте три отдельных определения (например):

#define TOP_CELL 0
#define MIDDLE_CELL 1
#define BOTTOM_CELL 2

Теперь переопределите метод layoutSubviews: и выполните что-то вроде следующего:

-(void) layoutSubviews {
    [super layoutSubviews];

    if([self tag] == BOTTOM_CELL) {

         self.layer.masksToBounds = NO;
         self.layer.shadowOffset = CGSizeMake(-10, 15);
         self.layer.shadowRadius = 5;
         self.layer.shadowOpacity = 0.5;
    }
    //else if middle_cell (Different shadowing)
    //else if top_cell (Different shadowing)
}

ПРИМЕЧАНИЕ. На самом деле я не уверен, что метод layoutSubviews является адекватным методом для этого, я просто знаю, что он вызывается после dequeueReusableCellWithIdentifier:, что важно для следующего шага.

Теперь, внутри вашего UITableViewDataSource, в вашем tableView:cellForRowAtIndexPath:

CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:ident];

if(indexPath.row == 0)
    [cell setTag:TOP_CELL];
else if(indexPath.row == (NUMBER_OF_ROWS - 1))
    [cell setTag:BOTTOM_CELL];
else
    [cell setTag: MIDDLE_CELL];

вуаля! затемненные участки

0 голосов
/ 25 декабря 2011

Вы всегда можете установить ShadowPath следующим образом:

myView.layer.shadowOpacity = 0.8;
myView.layer.shadowRadius = 5.0;
myView.layer.shadowOffset = CGSizeZero;
myView.layer.shadowPath = [UIBezierPath bezierPathWithRect:myView.layer.bounds].CGPath;

Обратите внимание, что для этого требуется QuartzCore или CoreGraphics, плохо помните.

В этой статье много теневых путей:http://nachbaur.com/blog/fun-shadow-effects-using-custom-calayer-shadowpaths

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...