Adding rounded corner and drop shadow to UICollectionViewCell

前端 未结 15 2636
逝去的感伤
逝去的感伤 2020-12-12 09:50

So I already went through various posts on adding 2nd view for adding shadow, but I still cannot get it to work if I want to add it in UICollectionViewCell. I s

相关标签:
15条回答
  • 2020-12-12 10:30

    Set the layer attributes for the cell, not 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]];
    
    0 讨论(0)
  • 2020-12-12 10:30

    I found an important thing: the UICollectionViewCell must have the backgroundColor as clear color in order to make these above work.

    0 讨论(0)
  • 2020-12-12 10:31

    Neither of these solutions worked for me. If you place all your subviews into the UICollectionViewCell content view, which you probably are, you can set the shadow on the cell's layer and the border on the contentView's layer to achieve both results.

    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
    
    0 讨论(0)
  • 2020-12-12 10:33

    Here's my answer, close to the others, but I add a corner radius to the layer otherwise the corners won't fill in correctly. Also, this makes a nice little extension on 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
        }
    }
    

    You can call it in collectionView(_:cellForItemAt:) of the datasource once you dequeue your cell.

    0 讨论(0)
  • 2020-12-12 10:35

    You simply need to (a) set cornerRadius and (b) set shadowPath to be a rounded rect with the same radius as cornerRadius:

    self.layer.cornerRadius = 10;
    self.layer.shadowPath = [[UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:self.layer.cornerRadius] CGPath];
    
    0 讨论(0)
  • 2020-12-12 10:37

    The answer of Mike Sabatini works fine, if you configure the cell properties directly on the collectionView cellForItemAt, but if you try to set them in awakeFromNib() of a custom UICollectionViewCell subclass, you will end with a wrong bezierPath set on the devices that doesn't match the width and height previously set in your Storyboard (IB).

    Solution for me was create a func inside the subclass of UICollectionViewCell and calling it from the cellForItemAt like this:

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

    And on the 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}
     }
    
    0 讨论(0)
提交回复
热议问题