0

I have a UIView and a shadow around it. The problem is that the shadow looks good in the simulator but not on a real device. Both simulator and my iPhone have the iOS version.

My code: I use it inside a UITableViewCell class.

override func awakeFromNib() {
    super.awakeFromNib()

    let shadowFrame: CGRect = cellView.layer.bounds
    let shadowPath: CGPath = UIBezierPath(rect: shadowFrame).cgPath
    cellView.layer.shadowOffset = CGSize(width: 0, height: 1)
    cellView.layer.shadowColor = UIColor.gray.cgColor
    cellView.layer.shadowRadius = 1
    cellView.layer.shadowOpacity = 0.6
    cellView.clipsToBounds = false
    cellView.layer.shadowPath = shadowPath

}
  1. The simulator, 2. my iPhone: simulator shadow

iPhone shadow

EDIT The iPhone 7 simulator shows the same shadow as my iPhone 6. Only the iPhone 7plus Simulator can display the shadow right. Is that a Xcode bug?

user3653164
  • 979
  • 1
  • 8
  • 24
  • small question: cellView is the contentView or is it self of the UITableViewCell ? – Mikael Nov 17 '16 at 10:17
  • also can you post a capture of the View debugger to see the properties of your shadow at runtime if available. – Mikael Nov 17 '16 at 10:20
  • you can also, put your code in a function and call it in the cellForRowAtIndexPath. awakeForNib is 'maybe' not the best option here - this is worth a test - – Mikael Nov 17 '16 at 10:22
  • `cellView` is a `UIView` I put inside the `UITableViewCell`. Same result for `cellForRowAtIndexPath`... – user3653164 Nov 17 '16 at 21:11
  • When I select the row/cell it animates and then I get the result I want. The shadow is displayed right after selecting it once – user3653164 Nov 17 '16 at 21:12
  • be careful o f putting your custom view not inside the UITableViewCell but inside the contentView. – Mikael Nov 18 '16 at 02:29

1 Answers1

1

This code will work fine when the dimensions of the view are the same as your nib. However, awakeFromNib is likely to be called before the autolayout engine has completed its layout passes, meaning cellView.layer.bounds will not be set to the dimensions that rendered on screen. You should try moving the setting of your shadow path to layoutSubviews in your UITableViewCell subclass or cellForRowAtIndexPath in your UITableViewDataSource

Update

You can also try to just observe when your table view cell's frame is set and update the shadow path then.

class MyTableViewCell: UITableViewCell
{
    var cellView: UIView?
    override var frame: CGRect
    {
        didSet
        {
            guard let cellView = self.cellView, self.frame != oldValue else { return }
            cellView.layer.shadowPath = UIBezierPath(rect: cellView.bounds).cgPath
        }
    }
}
Community
  • 1
  • 1
beyowulf
  • 15,101
  • 2
  • 34
  • 40
  • Moving it to `layoutSubviews` did'nt changed it. I can't use the `UIView` inside my `UITableViewCell` in the `cellForRowAtIndexPath`. Even when I use the `cell as! CellClassName` – user3653164 Nov 17 '16 at 03:14
  • Did you set the shadow path after calling `super.layoutSubviews()`? Why can't you? – beyowulf Nov 17 '16 at 04:03
  • I get a `has no member` error after the cast for my `cell`. And yes, I did set the shadow path after `super.layoutSubviews()`. – user3653164 Nov 17 '16 at 06:41
  • I don't understand why it's working in the simulator but not on my device. – user3653164 Nov 17 '16 at 07:06
  • Are you using the same simulator as the device? – beyowulf Nov 17 '16 at 14:32
  • No. I was testing it on an iPhone 7plus Simulator. My device is an iPhone 6. When I test it on an iPhone 7 Simulator I get the same (bad) result as on my iPhone 6. Only the 7plus Simulator shows the (right) result. – user3653164 Nov 17 '16 at 23:03
  • It sounds like it's correct for plus-sized devices for the reasons I discussed in my answer "This code will work fine when the dimensions of the view are the same as your nib. However, awakeFromNib is likely to be called before the autolayout engine has completed its layout passes..." You can confirm this by trying on the iPhone 6 plus simulator. You should move the setting of your shadow path to after the auto layout engine has finished its passes. You can try my answer [here](http://stackoverflow.com/a/38731793/5442445) if `layoutSubviews` doesn't work for you. – beyowulf Nov 18 '16 at 00:05
  • Can you please add a Swift version of you code? And where do I add this? – user3653164 Nov 18 '16 at 00:33