0

I am trying to establish a shadow on all four sides of my UIView in my ViewController — which works perfectly fine until I add constraints to the UIView via Xcode. How can I make the shadow of the UIView display on all four sides with set constraints for all sides?

Essentially, what I've discovered is that whenever I apply constraints via Xcode to the UIView that I have set the shadow around, the shadow does not appear under all four sides of the UIView. Instead, it floats to the left, leaving the right and bottom sides completely without shadowing. This can be seen in the screenshots beneath.

https://i.stack.imgur.com/BNvaW.jpg

class RegistrationViewController: UIViewController {
    @IBOutlet weak var signUpView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        signUpView.clipsToBounds = true
        signUpView.layer.cornerRadius = 20;
        signUpView.layer.shadowPath = UIBezierPath(roundedRect: signUpView.bounds, cornerRadius: signUpView.layer.cornerRadius).cgPath
        signUpView.layer.shouldRasterize = true
        signUpView.layer.shadowColor = UIColor.black.cgColor
        signUpView.layer.shadowOffset = .zero
        signUpView.layer.shadowOpacity = 1
        signUpView.layer.shadowRadius = 20
        signUpView.layer.masksToBounds = false

    // Do any additional setup after loading the view.
    }
}

Why is this happening and how can I add constraints while keeping the desired result?

Californium
  • 491
  • 4
  • 17

1 Answers1

2

In viewDidLoad, your constraints have not taken affect yet. So when you create your UIBezierPath, the bounds are not updated to the auto-layout constraints. The bounds that are used are probably the ones in your .xib file.

Move your shadowMakingPath into viewDidLayoutSubviews

override func viewDidLayoutSubviews() {
   super.viewDidLayoutSubivews()
   signUpView.layer.shadowPath = UIBezierPath(roundedRect: signUpView.bounds, cornerRadius: signUpView.layer.cornerRadius).cgPath
   signUpView.layer.shouldRasterize = true
   signUpView.layer.shadowColor = UIColor.black.cgColor
   signUpView.layer.shadowOffset = .zero
   signUpView.layer.shadowOpacity = 1
   signUpView.layer.shadowRadius = 20
   signUpView.layer.masksToBounds = false
}

More information .. Objective-C/Swift (iOS) When are the auto-constraints applied in the View/ViewController work flow?

Mocha
  • 2,035
  • 12
  • 29
  • I tried that but the result I'm getting is still the same. I created a viewWillLayoutSubviews function in the related file, any ideas what I could be doing wrong? And should I be updating the .xib file in some way? Sorry, I'm very new to Swift coding. – Californium Jan 09 '19 at 18:32
  • 1
    You shouldn't need to update the xib if your constraints are working. Instead of using bounds, try using frame? see updated answer. – Mocha Jan 09 '19 at 18:36
  • I did that, and now the shadow is floating to the right instead of left. Same result though. And are you referring to my .storyboard file by .xib? Otherwise, I don't have a .xib file set up. – Californium Jan 09 '19 at 18:40
  • Yes, a .xib is usually an individual screen in a .storyboard file (You don't need to worry about this for your problem). Can you screenshot us your UIView constraints and how it looks in your storyboard? – Mocha Jan 09 '19 at 18:45
  • Here you go. I hope that's enough! Basically, I just have a single UIView in the UIViewController with 40pt constraints on all sides. https://imgur.com/a/jrSmc8R – Californium Jan 09 '19 at 18:48
  • 1
    I'm not sure what the problem can be. Are you overriding the func and calling super? If you put a breakpoint in the viewdidLoad and viewWillLayoutSubviews can you po the signUpView.frame in both functions? – Mocha Jan 09 '19 at 18:51
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/186425/discussion-between-californium-and-mocha). – Californium Jan 09 '19 at 18:54