4

enter image description hereAfter autolayout (Constraints) How to make corner radius and shadow of the view ( even the view have some subview also ) and which method to write the code. If i write the code in viewdidload , viewDidAppear that i cant get the exact corner radius and shadow ?

This is my code which I do in viewWillLayoutSubview , I can get the corner radius but I cannot get shadow effects. If I remove view.layer.masksToBounds = true I can get shadow but its not corner only for base view not for its subviews ..

view.layer.cornerRadius = 10
view.layer.masksToBounds = true

view.layer.borderWidth = 1.0
view.layer.borderColor = UIColor.black.cgColor

view.layer.shadowColor = UIColor.black.cgColor
view.layer.shadowOffset = CGSize(width: 3, height: 3)
view.layer.shadowOpacity = 0.7
view.layer.shadowRadius = 4.0
user8343375
  • 59
  • 1
  • 3
  • 6
  • 2
    Possible duplicate for https://stackoverflow.com/questions/4754392/uiview-with-rounded-corners-and-drop-shadow – algrid Dec 13 '17 at 06:14
  • 3
    Possible duplicate of [UIView with rounded corners and drop shadow?](https://stackoverflow.com/questions/4754392/uiview-with-rounded-corners-and-drop-shadow) – Sunil Sharma Dec 13 '17 at 06:17
  • 1
    To achieve this I took two views one which will hold all subviews and another just an empty view of same constraints as of first view. Give corner radius to the view where all the subviews are there and give shadow to dummy view. – Sharad Chauhan Dec 13 '17 at 06:31

8 Answers8

8
    viewShadow.layer.cornerRadius = 12
    viewShadow.layer.masksToBounds = true;

    viewShadow.backgroundColor = UIColor.white
    viewShadow.layer.shadowColor = UIColor.lightGray.cgColor
    viewShadow.layer.shadowOpacity = 0.8
    viewShadow.layer.shadowOffset = CGSize(width: 0.0, height: 0.0)
    viewShadow.layer.shadowRadius = 6.0
    viewShadow.layer.masksToBounds = false

enter image description here

Tajinder singh
  • 738
  • 1
  • 9
  • 18
3

It depends on certain condition

  1. If you set autolayout constrains from storyboard and size(height ,width) of view is fixed then you can set corner radius in viewDidLoad.

  2. If you set autolayout constrains from storyboard and size(height ,width) of view is in ratio , so safe place for setting corner radius is viewWillLayoutSubview.

  3. If you set constraints programmatically then there also can be certain conditions.viewWillAppear,viewDidAppear,viewWillLayoutSubview,viewDidLayoutSubview all can be handy depending on your situation.

Kozmotronik
  • 2,080
  • 3
  • 10
  • 25
Vikky
  • 914
  • 1
  • 6
  • 16
  • 1
    try setting layer.masksToBounds = false – Vikky Dec 13 '17 at 05:56
  • If layer.masksToBounds = false then , I can get corner radius only for the base view, its subview are not getting cornerRadius. – user8343375 Dec 13 '17 at 06:00
  • I think you are required to set corner radius for each view – Vikky Dec 13 '17 at 06:02
  • But its not looks goods when i do corner radius for all the views – user8343375 Dec 13 '17 at 06:03
  • Is that any other alternative option to do that without set corner radius for each view ? – user8343375 Dec 13 '17 at 06:04
  • I don't think its possible but you are free to check if it can be done so ,as google is our friend.But you can solve it by doing so let subviews = yourView.subviews; for currentView in subviews { currentView.setRadius; } you can loop through all subview and set radius – Vikky Dec 13 '17 at 06:17
  • But this will clip all the subviews inside that view, even view s which is in middle. I think he is not expecting to do that. – Rahul Dasgupta Dec 13 '17 at 06:26
  • @RahulDasgupta can you explain why this will clip all subviews. – Vikky Dec 13 '17 at 06:45
  • @Vikky because you are setting corner radius for every subviews. – Rahul Dasgupta Dec 13 '17 at 06:51
  • @RahulDasgupta I don't think so. I have been using this approach all the time without any problem.Or may be i am unable to get your actual point what you are saying. – Vikky Dec 13 '17 at 07:00
  • @RahulDasgupta I don't understand how subviews can be clipped unless you are using clipToBounds and i am pretty sure here we are not using that. – Vikky Dec 13 '17 at 07:25
  • I mean not clipping but corner radius – Rahul Dasgupta Dec 13 '17 at 07:51
3

Add parentiew, parentView->View

set shadow and cornerRadius for parentView, maskToBounds = false

set cornerRadius for View, maskToBounds = true

Quyet Nguyen
  • 118
  • 8
2

It is not possible to set

layer.masksToBounds = true 

and get shadow because maskToBounds will clip everything which falls in bounds of the view. And since shadow is put on bounds so it clips that also. Only way is to keep all the subview away from bounds.

One more way is that .

Add your view as a subview of another view, lets call it parent view. Add shadow to parent view with

 layer.cornerRadius = 10
 layer.masksToBounds = false

In your view add

 layer.cornerRadius = 10
 layermasksToBounds = true 

This will work.

Rahul Dasgupta
  • 894
  • 6
  • 18
1

Add this code then after check in attribute inspector in storyboard it's shows you to set border color,shadow,radius.

extension UIView {

@IBInspectable
var cornerRadius: CGFloat {
    get {
        return layer.cornerRadius
    }
    set {
        layer.cornerRadius = newValue
        layer.masksToBounds = newValue > 0
    }
}

   @IBInspectable
   var borderWidth: CGFloat {
        get {
            return layer.borderWidth
        }
       set {
            layer.borderWidth = newValue
       }
     }

    @IBInspectable
    var borderColor: UIColor? {
        get {
            return UIColor(cgColor: layer.borderColor!)
        }
        set {
            layer.borderColor = newValue?.cgColor
        }
    }

    @IBInspectable
   var shadowRadius: CGFloat {
        get {
            return layer.shadowRadius
        }
        set {
            layer.shadowColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1).cgColor
            layer.shadowOffset = CGSize(width: 0, height: 2)
            layer.shadowOpacity = 0.5
            layer.masksToBounds = false
            layer.shadowRadius = newValue
        }
    }
}

Image look like below:enter image description here

V D Purohit
  • 1,179
  • 1
  • 10
  • 23
1

To add corner radius and shadow at the same time, you need to fake this view by adding another view of the same size, or rather subview on it.

So first, Add your view, Let's say that containerView it's like your parent view/superview that we will add shadow normally to it by:

containerView.backgroundColor = .clear
containerView.layer.shadowColor = UIColor.lightGray.cgColor
// or if you'd like to add shadow color in black, it's what you prefer
//containerView.layer.shadowColor = UIColor.black.cgColor
containerView.layer.shadowOffset = .zero
containerView.layer.shadowOpacity = 0.3
// shadow radius is optional, you can add or comment it
containerView.layer.shadowRadius = 8
containerView.layer.masksToBounds = false

then you can create subview on the containerView by:

containerView.addSubview(subContainerView)
subContainerView.backgroundColor = .white
subContainerView.layer.cornerRadius = 8
subContainerView.layer.masksToBounds = true

The containerView will reflect the shadow to the subContainerView which is really corner radius.

Note: If you'd like to change the background color of the view, Change the subContainerView background.

Check this simple project

Elserafy
  • 51
  • 3
0

Try this answer:

UIView * paintView=[[UIView alloc]initWithFrame:CGRectMake(50, 150, 320, 430)];
[paintView setBackgroundColor:[UIColor yellowColor]];

paintView.layer.masksToBounds = NO;
paintView.layer.cornerRadius = 5;
paintView.layer.shadowOffset = CGSizeMake(-.2f, .2f);
paintView.layer.shadowRadius = 3;
paintView.layer.shadowOpacity = 0.8;
paintView.layer.shadowColor = [[UIColor redColor] CGColor];

UIBezierPath *path = [UIBezierPath bezierPathWithRect:paintView.bounds];
paintView.layer.shadowPath = path.CGPath;
[self.view addSubview:paintView];
Mukesh
  • 777
  • 7
  • 20
-1

you can try this :

func addShadow(container : UIView){

    container.layer.shadowColor = UIColor.black.cgColor
    container.layer.shadowOffset = CGSize(width: 1.0, height: 1.0)
    container.layer.shadowOpacity = 0.2
    container.layer.shadowRadius = 5.0
    container.layer.masksToBounds = false
    
}
Ammar
  • 380
  • 6
  • 16