将圆角和阴影添加到UICollectionViewCell

时间:2012-11-22 03:10:57

标签: iphone ios uicollectionviewcell

所以我已经通过添加第二个视图添加阴影的各种帖子,但如果我想在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

16 个答案:

答案 0 :(得分:158)

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

答案 1 :(得分:26)

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

答案 2 :(得分:20)

如果它有帮助:这是圆角的快速:

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

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

中使用它

享受!

答案 3 :(得分:14)

设置单元格的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]];

答案 4 :(得分:10)

此处 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

答案 5 :(得分:8)

您只需要(a)设置cornerRadius和(b)将shadowPath设置为圆角矩形,其半径与cornerRadius相同:

self.layer.cornerRadius = 10;
self.layer.shadowPath = [[UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:self.layer.cornerRadius] CGPath];

答案 6 :(得分: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;

答案 7 :(得分: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

答案 8 :(得分:3)

SWIFT 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

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

答案 9 :(得分:2)

如果您直接在collectionView cellForItemAt上配置单元格属性,那么Mike Sabatini的答案就可以很好地工作,但是如果您尝试在自定义UICollectionViewCell子类的awakeFromNib()中设置它们,则会以错误的bezierPath结尾与先前在情节提要(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}
 }

答案 10 :(得分:2)

我发现了一件重要的事情:UICollectionViewCell必须具有clear颜色的backgroundColor才能使上述功能起作用。

答案 11 :(得分:1)

您可以在创建 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

答案 12 :(得分:0)

如果您是从xib加载单元格,那么awakeFromNib是放置代码的位置。

Unable to create session from { "desiredCapabilities": { "browserName": 
"android", "platform": "ANDROID" }, "capabilities": { "firstMatch": [ { 
"browserName": "android", "platformName": "android" } ] } } Build info: 
version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:25:53' 
System info: host: 'DESKTOP-N27RM9V', ip: '192.168.0.4', os.name: 'Windows 
10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_211' Driver 
info: driver.version: unknown

答案 13 :(得分:0)

这是我的答案,与其他答案很接近,但是我在图层上添加了一个圆角半径,否则这些圆角将无法正确填充。此外,这在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 :(得分:0)

这是我的解决方案。它与其他答案类似,但有一个主要区别。它不会创建依赖于视图范围的路径。每当您根据边界创建路径并将其提供给图层时,调整大小时都会遇到问题,并且需要设置方法来更新路径。

一个更简单的解决方案是避免使用任何与范围相关的内容。

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就会在内部完成所有工作。

答案 15 :(得分:0)

我使用以下方法来实现这种效果:

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
    }
}