Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
666 views
in Technique[技术] by (71.8m points)

swift - UITableViewCell: rounded corners and shadow

I'm changing the width of a UITableViewCell so that the cell is smaller but the user can still scroll along the edges of the tableview.

override func layoutSubviews() {        
    // Set the width of the cell
    self.bounds = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, self.bounds.size.width - 40, self.bounds.size.height)
    super.layoutSubviews()
}

Then I round the corners:

cell.layer.cornerRadius = 8
cell.layer.masksToBounds = true

All good so far. Problem happens with the shadow. The bounds are masked, so the shadow obviously won't show up. I've looked up other answers but can't seem to figure out how to round the corners along the bounds and show the shadow.

cell.layer.shadowOffset = CGSizeMake(0, 0)
cell.layer.shadowColor = UIColor.blackColor().CGColor
cell.layer.shadowOpacity = 0.23
cell.layer.shadowRadius = 4

So my question –?how do I reduce the width, round the corners, and add a shadow to a UITableViewCell at the same time?

Update: Trying R Moyer's answer

Trying R Moyer's answer

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This question comes at a good time! I literally JUST solved this same issue myself.

  1. Create a UIView (let's refer to it as mainBackground) inside your cell's Content View. This will contain all of your cell's content. Position it and apply necessary constraints in the Storyboard.
  2. Create another UIView. This one will be the one with the shadow (let's refer to it as shadowLayer). Position it exactly as you did mainBackground, but behind it, and apply the same constraints.
  3. Now you should be able to set the rounded corners and the shadows as follows:

    cell.mainBackground.layer.cornerRadius = 8  
    cell.mainBackground.layer.masksToBounds = true
    
    cell.shadowLayer.layer.masksToBounds = false
    cell.shadowLayer.layer.shadowOffset = CGSizeMake(0, 0)
    cell.shadowLayer.layer.shadowColor = UIColor.blackColor().CGColor
    cell.shadowLayer.layer.shadowOpacity = 0.23
    cell.shadowLayer.layer.shadowRadius = 4
    

However, the problem here is: calculating the shadow for every single cell is a slow task. You'll notice some serious lag when you scroll through your table. The best way to fix this is to define a UIBezierPath for the shadow, then rasterize it. So you may want to do this:

cell.shadowLayer.layer.shadowPath = UIBezierPath(roundedRect: cell.shadowLayer.bounds, byRoundingCorners: .AllCorners, cornerRadii: CGSize(width: 8, height: 8)).CGPath
cell.shadowLayer.layer.shouldRasterize = true
cell.shadowLayer.layer.rasterizationScale = UIScreen.mainScreen().scale

But this creates a new problem! The shape of the UIBezierPath depends on shadowLayer's bounds, but the bounds are not properly set by the time cellForRowAtIndexPath is called. So, you need to adjust the shadowPath based on shadowLayer's bounds. The best way to do this is to subclass UIView, and add a property observer to the bounds property. Then set all the properties for the shadow in didSet. Remember to change the class of your shadowLayer in the storyboard to match your new subclass.

class ShadowView: UIView {
    override var bounds: CGRect {
        didSet {
            setupShadow()
        }
    }

    private func setupShadow() {
        self.layer.cornerRadius = 8
        self.layer.shadowOffset = CGSize(width: 0, height: 3)
        self.layer.shadowRadius = 3
        self.layer.shadowOpacity = 0.3
        self.layer.shadowPath = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: 8, height: 8)).cgPath
        self.layer.shouldRasterize = true
        self.layer.rasterizationScale = UIScreen.main.scale
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...