简体   繁体   中英

How to make UICollectionViewCells have rounded corners and drop shadows?

I've seen some other answers to similar questions, but none of the solutions have worked for me, even with some tweaking.

As the title suggests, I would like my UICollectionViewCell s to have rounded corners and drop shadows (or shadows on all sides except the top). What I have done so far is to add two views to my UICollectionViewCell - mainView , which displays the cell's necessary content and has rounded corners, and shadowView , which has the shadow. Neither view is a subview of the other, they exist together in the same cell. They are both the exact same dimensions, and mainView is obviously displayed on top of shadowView . Here is my current code implementation:

let mainView = cell.viewWithTag(1003) as! UIView       
mainView.layer.cornerRadius = 10.0
mainView.layer.borderWidth = 1.0
mainView.layer.borderColor = UIColor.clear.cgColor
mainView.layer.masksToBounds = true

let shadowView = cell.viewWithTag(1002) as! UIView
shadowView.layer.shadowColor = UIColor.black.cgColor
shadowView.layer.shadowOffset = CGSize(width: 0, height: 2.0)
shadowView.layer.shadowRadius = 2.0
shadowView.layer.shadowOpacity = 0.5
shadowView.layer.masksToBounds = false
shadowView.layer.shadowPath = UIBezierPath(roundedRect: shadowView.bounds, cornerRadius: mainView.layer.cornerRadius).cgPath

Here is what this code produces: 在此处输入图片说明 One would think that mainView 's corners aren't rounded enough, and that the shadow isn't big enough.

However, upon removing shadowView and setting the UICollectionView 's background to black, you can see that mainView 's corners are actually quite rounded: 在此处输入图片说明

So this implies that the issue is with shadowView 's shadow size. However, I have tried increasing the shadow offsets and the the shadow radius, which did nothing. Most changes either produced a very thick shadow around mainView , decreased mainView 's rounding even more, or did nothing.

Here is an image of the relevant UITableViewCell 's view hierarchy in the Storyboard: 在此处输入图片说明

Here is the Cell code:

class CollectionViewCell: UICollectionViewCell {
    override init(frame: CGRect) {
        super.init(frame: frame)


        layer.shadowColor = UIColor.lightGray.cgColor
        layer.shadowOffset = CGSize(width: 0, height: 2.0)
        layer.shadowRadius = 5.0
        layer.shadowOpacity = 1.0
        layer.masksToBounds = false
        layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: contentView.layer.cornerRadius).cgPath
        layer.backgroundColor = UIColor.clear.cgColor

        contentView.layer.masksToBounds = true
        layer.cornerRadius = 10
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

Here is the usage code:

import UIKit

private let reuseIdentifier = "Cell"

class CollectionViewController: UICollectionViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        self.collectionView!.register(CollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
        (self.collectionView.collectionViewLayout as! UICollectionViewFlowLayout).itemSize = CGSize(width: 100, height: 100)
    }

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
        cell.backgroundColor = .white
        return cell
    }
}

Here is the result: 在此处输入图片说明

Update

Thanks for the chat on Hangouts. I downloaded your code and mainView and shadowView was nil.

  • I noticed that you're not comfortable with CollectionViewCells.

With that being said. I'm more than happy to introduce our friend Runtime Attributes

Without touching your code. Select a view and add your runtime attribute key and set the value.

SCR1

Output:

Scre1

Go ahead, and do the work for the shadow and the rest.


The mainView is rounded, but the shadowView is taking all the credit.

You need to enable clipsToBounds on both views:

mainView.clipsToBounds = true

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM