Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shadow effect is not displaying properly for UIView

Tags:

ios

swift

I have a login screen as below. Around each text field I have added a view and for that view I want to display a drop shadow. I kind of achieved what I was trying but this thing is not working for iPhone Plus (6+,8+) devices.

You can see the difference below.

iPhone 8+:-

enter image description here

iPhone 8:-

enter image description here

Here is my code

extension UIView {
    func addShadow() {        
        layer.cornerRadius = 8
        layer.masksToBounds = true

        layer.shadowColor = UIColor.lightGray.cgColor
        layer.shadowOffset = CGSize(width: 0, height: 1.0)
        layer.shadowRadius = 2.0
        layer.shadowOpacity = 0.5
        layer.masksToBounds = false

        layer.shadowPath = UIBezierPath(roundedRect: self.bounds,cornerRadius:8).cgPath
    }
}

How I can fix this properly?

like image 580
aqsa arshad Avatar asked Apr 05 '18 05:04

aqsa arshad


2 Answers

Since the views may be resized you should update your shadowPath after resizing because it has a fixed size. Unfortunately this can't be done in an extension, because you need to overwrite layoutSubview(). But you may call addShadow() from viewDidLayoutSubviews() from your view controller again for each text field.

You may also modify your extension to only update the path:

extension UIView {
    func addShadow() {        
        layer.cornerRadius = 8

        layer.shadowColor = UIColor.lightGray.cgColor
        layer.shadowOffset = CGSize(width: 0, height: 1.0)
        layer.shadowRadius = 2.0
        layer.shadowOpacity = 0.5
        layer.masksToBounds = false

        updateShadow()
    }
    func updateShadow() {
        layer.shadowPath = UIBezierPath(roundedRect: self.bounds,cornerRadius:8).cgPath
    }  
}

With this you should call updateShadow() from viewDidLayoutSubviews() for each view with a shadow.

If you use a custom subclass for your text fields you may put the updateShadow() call into layoutSubviews(). So you need not to call it from the view controller.

like image 139
clemens Avatar answered Nov 14 '22 23:11

clemens


You are building the view on iPhone 8 on storyboard. So when you run it on iPhone 8+/ 6+, view gets resized but shadow does not get updated.

enter image description here

Put layoutIfNeeded() before adding shadowPath to layer:

Updated code will look like:

func addShadow() {
    layer.cornerRadius = 8
    layer.masksToBounds = true

    layer.shadowColor = UIColor.lightGray.cgColor
    layer.shadowOffset = CGSize(width: 0, height: 1.0)
    layer.shadowRadius = 2.0
    layer.shadowOpacity = 0.5
    layer.masksToBounds = false

    layoutIfNeeded()
    layer.shadowPath = UIBezierPath(roundedRect: self.bounds,cornerRadius: 8).cgPath
}
like image 28
Ankit Jayaswal Avatar answered Nov 14 '22 22:11

Ankit Jayaswal