Добавление округленного угла и тени для UICollectionViewCell
Итак, я уже просматривал различные сообщения о добавлении второго представления для добавления тени, но я все равно не могу заставить его работать, если я хочу добавить его в UICollectionViewCell
. Я подклассифицировал UICollectionViewCell
, и вот мой код, где я добавляю различные элементы пользовательского интерфейса в представление содержимого ячейки и добавляю тень к слою:
[self.contentView setBackgroundColor:[UIColor whiteColor]];
self.layer.masksToBounds = NO;
self.layer.shadowOffset = CGSizeMake(0, 1);
self.layer.shadowRadius = 1.0;
self.layer.shadowColor = [UIColor blackColor].CGColor;
self.layer.shadowOpacity = 0.5;
[self.layer setShadowPath:[[UIBezierPath bezierPathWithRect:self.bounds] CGPath]];
Я хотел бы знать, как добавить округленный угол и тень к UICollectionViewCell
.
Ответы
Ответ 1
Ни одно из этих решений не помогло мне. Если вы поместите все свои подпредставления в представление контента UICollectionViewCell, которым вы, вероятно, являетесь, вы можете установить тень на слое ячеек и границу на слое contentView для достижения обоих результатов.
cell.contentView.layer.cornerRadius = 2.0f;
cell.contentView.layer.borderWidth = 1.0f;
cell.contentView.layer.borderColor = [UIColor clearColor].CGColor;
cell.contentView.layer.masksToBounds = YES;
cell.layer.shadowColor = [UIColor blackColor].CGColor;
cell.layer.shadowOffset = CGSizeMake(0, 2.0f);
cell.layer.shadowRadius = 2.0f;
cell.layer.shadowOpacity = 0.5f;
cell.layer.masksToBounds = NO;
cell.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:cell.bounds cornerRadius:cell.contentView.layer.cornerRadius].CGPath;
Swift 3.0
self.contentView.layer.cornerRadius = 2.0
self.contentView.layer.borderWidth = 1.0
self.contentView.layer.borderColor = UIColor.clear.cgColor
self.contentView.layer.masksToBounds = true
self.layer.shadowColor = UIColor.black.cgColor
self.layer.shadowOffset = CGSize(width: 0, height: 2.0)
self.layer.shadowRadius = 2.0
self.layer.shadowOpacity = 0.5
self.layer.masksToBounds = false
self.layer.shadowPath = UIBezierPath(roundedRect: self.bounds, cornerRadius: self.contentView.layer.cornerRadius).cgPath
Ответ 2
Версия Swift 3:
cell.contentView.layer.cornerRadius = 10
cell.contentView.layer.borderWidth = 1.0
cell.contentView.layer.borderColor = UIColor.clear.cgColor
cell.contentView.layer.masksToBounds = true
cell.layer.shadowColor = UIColor.gray.cgColor
cell.layer.shadowOffset = CGSize(width: 0, height: 2.0)
cell.layer.shadowRadius = 2.0
cell.layer.shadowOpacity = 1.0
cell.layer.masksToBounds = false
cell.layer.shadowPath = UIBezierPath(roundedRect:cell.bounds, cornerRadius:cell.contentView.layer.cornerRadius).cgPath
Ответ 3
В случае, если это помогает: Вот быстрое закругление углов:
cell.layer.cornerRadius = 10
cell.layer.masksToBounds = true
с ячейкой, являющейся переменной, управляющей ячейкой: часто вы будете использовать это в override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) → UICollectionViewCell
Наслаждайтесь!
Ответ 4
Задайте атрибуты layer
для ячейки, а не contentView
.
CALayer * layer = [cell layer];
[layer setShadowOffset:CGSizeMake(0, 2)];
[layer setShadowRadius:1.0];
[layer setShadowColor:[UIColor redColor].CGColor] ;
[layer setShadowOpacity:0.5];
[layer setShadowPath:[[UIBezierPath bezierPathWithRect:cell.bounds] CGPath]];
Ответ 5
Вот решение Swift 4, обновленное, чтобы закруглить все углы, а не только верхние углы:
contentView.layer.cornerRadius = 6.0
contentView.layer.borderWidth = 1.0
contentView.layer.borderColor = UIColor.clear.cgColor
contentView.layer.masksToBounds = true
layer.shadowColor = UIColor.lightGray.cgColor
layer.shadowOffset = CGSize(width: 0, height: 2.0)
layer.shadowRadius = 6.0
layer.shadowOpacity = 1.0
layer.masksToBounds = false
layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: contentView.layer.cornerRadius).cgPath
layer.backgroundColor = UIColor.clear.cgColor
Ответ 6
Вам просто нужно (a) установить cornerRadius
и (b) установить shadowPath
как закругленный прямоугольник с тем же радиусом, что и cornerRadius
:
self.layer.cornerRadius = 10;
self.layer.shadowPath = [[UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:self.layer.cornerRadius] CGPath];
Ответ 7
Я должен был сделать небольшие изменения для Swift:
cell.contentView.layer.cornerRadius = 2.0;
cell.contentView.layer.borderWidth = 1.0;
cell.contentView.layer.borderColor = UIColor.clearColor().CGColor;
cell.contentView.layer.masksToBounds = true;
cell.layer.shadowColor = UIColor.grayColor().CGColor;
cell.layer.shadowOffset = CGSizeMake(0, 2.0);
cell.layer.shadowRadius = 2.0;
cell.layer.shadowOpacity = 1.0;
cell.layer.masksToBounds = false;
cell.layer.shadowPath = UIBezierPath(roundedRect:cell.bounds, cornerRadius:cell.contentView.layer.cornerRadius).CGPath;
Ответ 8
SWIFT 4.2
Нужно добавить это в вашей пользовательской ячейке или cellForItemAt: если вы используете cellForItemAt: подход замените себя → ячейка
self.layer.cornerRadius = 10
self.layer.borderWidth = 1.0
self.layer.borderColor = UIColor.lightGray.cgColor
self.layer.backgroundColor = UIColor.white.cgColor
self.layer.shadowColor = UIColor.gray.cgColor
self.layer.shadowOffset = CGSize(width: 2.0, height: 4.0)
self.layer.shadowRadius = 2.0
self.layer.shadowOpacity = 1.0
self.layer.masksToBounds = false
Это даст вам ячейку с закругленной границей и падающей тенью.
Ответ 9
Этот работал для меня
cell.contentView.layer.cornerRadius = 5.0
cell.contentView.layer.borderColor = UIColor.gray.withAlphaComponent(0.5).cgColor
cell.contentView.layer.borderWidth = 0.5
let border = CALayer()
let width = CGFloat(2.0)
border.borderColor = UIColor.darkGray.cgColor
border.frame = CGRect(x: 0, y: cell.contentView.frame.size.height - width, width: cell.contentView.frame.size.width, height: cell.contentView.frame.size.height)
border.borderWidth = width
cell.contentView.layer.addSublayer(border)
cell.contentView.layer.masksToBounds = true
cell.contentView.clipsToBounds = true
Ответ 10
Ответ Майка Сабатини работает нормально, если вы настраиваете свойства ячейки непосредственно в collectionView cellForItemAt, но если вы попытаетесь установить их в awakeFromNib() пользовательского подкласса UICollectionViewCell, у вас будет неправильный bezierPath, установленный на устройствах, которые не работают. не соответствует ширине и высоте, ранее установленным в раскадровке (IB).
Решением для меня было создать функцию внутри подкласса UICollectionViewCell и вызвать ее из cellForItemAt следующим образом:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellID", for: indexPath) as? CustomCollectionViewCell{
cell.configure())
return cell
}
else {
return UICollectionViewCell()
}
}
И на CustomCollectionViewCell.swift:
class CustomCollectionViewCell: UICollectionViewCell{
func configure() {
contentView.layer.cornerRadius = 20
contentView.layer.borderWidth = 1.0
contentView.layer.borderColor = UIColor.clear.cgColor
contentView.layer.masksToBounds = true
layer.shadowColor = UIColor.black.cgColor
layer.shadowOffset = CGSize(width: 0, height: 2.0)
layer.shadowRadius = 2.0
layer.shadowOpacity = 0.5
layer.masksToBounds = false
layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: contentView.layer.cornerRadius).cgPath}
}
Ответ 11
Вы можете установить цвет тени, радиус и смещение в методе UICollectionViewDataSource при создании UICollectionViewCell
cell.layer.shadowColor = UIColor.gray.cgColor
cell.layer.shadowOffset = CGSize(width: 0, height: 2.0)
cell.layer.shadowRadius = 1.0
cell.layer.shadowOpacity = 0.5
cell.layer.masksToBounds = false
Ответ 12
Если вы загружаете ячейку из xib, тогда awakeFromNib - это место, куда нужно поместить код.
class MyCollectionViewCell: UICollectionViewCell {
override func awakeFromNib() {
layer.cornerRadius = 7
layer.masksToBounds = true
}
}
Ответ 13
Вот мой ответ, близкий к остальным, но я добавляю угловой радиус к слою, иначе углы не будут заполняться правильно. Кроме того, это делает небольшое небольшое расширение для UICollectionViewCell
.
extension UICollectionViewCell {
func shadowDecorate() {
let radius: CGFloat = 10
contentView.layer.cornerRadius = radius
contentView.layer.borderWidth = 1
contentView.layer.borderColor = UIColor.clear.cgColor
contentView.layer.masksToBounds = true
layer.shadowColor = UIColor.black.cgColor
layer.shadowOffset = CGSize(width: 0, height: 1.0)
layer.shadowRadius = 2.0
layer.shadowOpacity = 0.5
layer.masksToBounds = false
layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: radius).cgPath
layer.cornerRadius = radius
}
}
Вы можете вызвать его в collectionView(_:cellForItemAt:)
источника данных, как только удалите свою ячейку из очереди.
Ответ 14
Вот мое решение. Это похоже на другие ответы, с одним ключевым отличием. Это не создает путь, который зависит от границ представления. Каждый раз, когда вы создаете путь на основе границ и предоставляете его слою, вы можете столкнуться с проблемами при его изменении, и вам необходимо настроить методы для обновления пути.
Более простое решение - избегать использования всего, что зависит от границ.
let radius: CGFloat = 10
self.contentView.layer.cornerRadius = radius
// Always mask the inside view
self.contentView.layer.masksToBounds = true
self.layer.shadowColor = UIColor.black.cgColor
self.layer.shadowOffset = CGSize(width: 0, height: 1.0)
self.layer.shadowRadius = 3.0
self.layer.shadowOpacity = 0.5
// Never mask the shadow as it falls outside the view
self.layer.masksToBounds = false
// Matching the contentView radius here will keep the shadow
// in sync with the contentView rounded shape
self.layer.cornerRadius = radius
Теперь, когда когда-либо изменится размер ячеек, API представления сделает всю работу внутренне.