118

因此,我已经阅读了有关添加第二个视图以添加阴影的各种帖子,但如果我想将它添加到UICollectionViewCell. 我进行了子类UICollectionViewCell化,这是我的代码,其中我将各种 UI 元素添加到单元格的内容视图并为图层添加阴影:

[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.

4

16 回答 16

206

这些解决方案都不适合我。如果您将所有子视图放入 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;

斯威夫特 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
于 2014-08-25T19:44:47.263 回答
35

斯威夫特 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
于 2016-10-20T18:04:49.623 回答
27

如果它有帮助:这是圆角的快捷方式:

cell.layer.cornerRadius = 10
cell.layer.masksToBounds = true

单元格是控制单元格的变量:通常,您将在override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell

享受!

于 2015-10-04T13:22:32.320 回答
22

这里是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
于 2018-05-16T09:05:04.493 回答
21

这是我的答案,与其他答案很接近,但我在图层中添加了一个角半径,否则角将无法正确填充。此外,这对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:)将单元格出列后,您可以在数据源中调用它。

于 2019-07-13T20:13:03.927 回答
16

设置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]];
于 2012-12-04T18:45:36.440 回答
16

斯威夫特 4.2

应该将其添加到您的自定义单元格或 cellForItemAt:如果您使用的是 cellForItemAt:方法替换 self -> cell

        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

这将为您提供一个带有圆形边框和阴影的单元格。

于 2019-04-19T12:29:14.563 回答
8

您只需(a)设置cornerRadius和(b)设置shadowPath为具有相同半径的圆角矩形cornerRadius

self.layer.cornerRadius = 10;
self.layer.shadowPath = [[UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:self.layer.cornerRadius] CGPath];
于 2012-12-31T18:05:40.473 回答
7

这是我对解决方案的看法。它与其他答案相似,但有一个关键区别。它不会创建依赖于视图边界的路径。每当您基于边界创建路径并将其提供给图层时,您可能会在调整大小时遇到​​问题,并且需要设置方法来更新路径。

一个更简单的解决方案是避免使用任何依赖于边界的东西。

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's rounded shape
self.layer.cornerRadius = radius

现在,当单元格大小发生变化时,视图 API 将在内部完成所有工作。

于 2019-07-23T17:50:14.653 回答
6

我不得不为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;
于 2015-12-15T17:59:57.767 回答
5

我使用以下方法来完成这种效果:

extension UICollectionViewCell {
    /// Call this method from `prepareForReuse`, because the cell needs to be already rendered (and have a size) in order for this to work
    func shadowDecorate(radius: CGFloat = 8,
                        shadowColor: UIColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.3),
                        shadowOffset: CGSize = CGSize(width: 0, height: 1.0),
                        shadowRadius: CGFloat = 3,
                        shadowOpacity: Float = 1) {
        contentView.layer.cornerRadius = radius
        contentView.layer.borderWidth = 1
        contentView.layer.borderColor = UIColor.clear.cgColor
        contentView.layer.masksToBounds = true

        layer.shadowColor = shadowColor.cgColor
        layer.shadowOffset = shadowOffset
        layer.shadowRadius = shadowRadius
        layer.shadowOpacity = shadowOpacity
        layer.masksToBounds = false
        layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: radius).cgPath
        layer.cornerRadius = radius
    }
}
于 2019-11-21T14:18:03.783 回答
4

Mike Sabatini 的答案工作正常,如果您直接在 collectionView cellForItemAt 上配置单元格属性,但如果您尝试在自定义 UICollectionViewCell 子类的 awakeFromNib() 中设置它们,您将在设备上设置错误的 bezierPath 结束'与您之前在 Storyboard (IB) 中设置的宽度和高度不匹配。

我的解决方案是在 UICollectionViewCell 的子类中创建一个 func 并从 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}
 }
于 2018-10-26T04:29:38.403 回答
3

这个对我有用

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
于 2017-10-10T06:09:42.453 回答
2

我发现了一件重要的事情: UICollectionViewCell 必须将 backgroundColor 作为clear颜色才能使上述这些工作。

于 2020-02-12T06:06:44.490 回答
2

您可以在创建UICollectionViewCell时在UICollectionViewDataSource方法中设置阴影颜色、半径和偏移量

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
于 2018-06-27T13:00:24.997 回答
0

斯威夫特 5、Xcode 13、iOS 14

首先配置您的收藏,如下所示:

self.collectionView.clipsToBounds = false

然后配置您的单元格,如下所示:

override func awakeFromNib() {
    super.awakeFromNib()
    
    self.configView()
}
    
private func configView() {
    self.clipsToBounds = false
    self.backgroundColor = .systemBackground
    self.layer.cornerRadius = 10
    self.layer.shadowColor = UIColor.black.cgColor
    self.layer.shadowOffset = CGSize(width: 0, height: 0.0)
    self.layer.shadowRadius = 10
    self.layer.shadowOpacity = 0.2
}

请注意这两个“clipToBounds = false”命令。

只是。

于 2021-12-27T13:39:43.920 回答