UIView with rounded corners and drop shadow?

前端 未结 30 2604
一整个雨季
一整个雨季 2020-11-22 08:00

I’ve been working on an application for a couple of years and received a simple design request: Round the corners on a UIView and add a drop shadow.To do as given below.

相关标签:
30条回答
  • 2020-11-22 08:10

    I have tried so many solutions from this post and ended up with the below solution. This is full proof solution unless you need to drop shadow on a clear color view.

    - (void)addShadowWithRadius:(CGFloat)shadowRadius withOpacity:(CGFloat)shadowOpacity withOffset:(CGSize)shadowOffset withColor:(UIColor *)shadowColor withCornerradius:(CGFloat)cornerRadius
    {
        UIView *viewShadow = [[UIView alloc]initWithFrame:self.frame];
        viewShadow.backgroundColor = [UIColor whiteColor];
        viewShadow.layer.shadowColor = shadowColor.CGColor;
        viewShadow.layer.shadowOffset = shadowOffset;
        viewShadow.layer.shadowRadius = shadowRadius;
        viewShadow.layer.shadowOpacity = shadowOpacity;
        viewShadow.layer.cornerRadius = cornerRadius;
        viewShadow.layer.masksToBounds = NO;
        [self.superview insertSubview:viewShadow belowSubview:self];
    
        [viewShadow setTranslatesAutoresizingMaskIntoConstraints:NO];
        [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:viewShadow attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0]];
        [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:viewShadow attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0]];
        [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:viewShadow attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:viewShadow attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]];
        [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:viewShadow attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:viewShadow attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0]];
        [self layoutIfNeeded];
    
        self.layer.cornerRadius = cornerRadius;
        self.layer.masksToBounds = YES;
    }
    
    0 讨论(0)
  • 2020-11-22 08:12

    One way to do this is to put the view with rounded corners in a view with the drop shadow.

    UIView* roundedView = [[UIView alloc] initWithFrame: frame];
    roundedView.layer.cornerRadius = 5.0;
    roundedView.layer.masksToBounds = YES;
    
    UIView* shadowView = [[UIView alloc] initWithFrame: frame];
    shadowView.layer.shadowColor = [UIColor blackColor].CGColor;
    shadowView.layer.shadowRadius = 5.0;
    shadowView.layer.shadowOffset = CGSizeMake(3.0, 3.0);
    shadowView.layer.shadowOpacity = 1.0;
    [shadowView addSubview: roundedView];
    

    Then you can add the shadowView wherever you want.

    0 讨论(0)
  • 2020-11-22 08:13

    After one whole day research of the round corner view with shadow, I'm glad to post my custom uiview class here, hope to end this question:

    RoundCornerShadowView.h

    #import <UIKit/UIKit.h>
    
    @interface RoundCornerShadowView : UIView
    
    @end
    

    RoundCornerShadowView.m

    #import "RoundCornerShadowView.h"
    
    @implementation RoundCornerShadowView
    
    // *** must override this method, not the other method ***
    // otherwise, the background corner doesn't disappear....
    // @2015/05/29
    -(void) layoutSubviews {
        [super layoutSubviews];//is must to ensure rightly layout children view
    
        //1. first, create Inner layer with content
        CALayer *innerView = [CALayer layer];
        innerView.frame = CGRectMake(0,0,self.bounds.size.width,self.bounds.size.height);
        //instead of: innerView.frame = self.frame;
        innerView.borderWidth = 1.0f;
        innerView.cornerRadius = 6.0f;
        innerView.masksToBounds = YES;
        innerView.borderColor = [[UIColor lightGrayColor] CGColor];
        innerView.backgroundColor = [[UIColor whiteColor] CGColor];
        //put the layer to the BOTTOM of layers is also a MUST step...
        //otherwise this layer will overlay the sub uiviews in current uiview...
        [self.layer insertSublayer:innerView atIndex:0];
    
        //2. then, create shadow with self layer
        self.layer.masksToBounds = NO;
        self.layer.shadowColor = [[UIColor darkGrayColor] CGColor];
        self.layer.shadowOpacity = 0.4f;
        //shadow length
        self.layer.shadowRadius = 2.0f;
        //no offset
        self.layer.shadowOffset = CGSizeMake(0, 0);
        //right down shadow
        //[self.layer setShadowOffset: CGSizeMake(1.0f, 1.0f)];
    
        //3. last but important, MUST clear current view background color, or the color will show in the corner!
        self.backgroundColor = [UIColor clearColor];
    }
    
    @end
    

    so, NO need to add subview in view or below in target view, just add one layer in current view, and do 3 step to complete it!

    take a close look at to the comments in the code, it's helpful to understanding the component!

    0 讨论(0)
  • 2020-11-22 08:13

    Here is the solution for masksToBounds conflict problem, it works for me.

    After you set the corderRadius/borderColor/shadow and so on, set masksToBounds as NO:

    v.layer.masksToBounds = NO;
    
    0 讨论(0)
  • 2020-11-22 08:14

    Here is my version in Swift 3 for a UIView

    let corners:UIRectCorner = [.bottomLeft, .topRight]
    let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
    let mask = CAShapeLayer()
    
    mask.path = path.cgPath
    mask.fillColor = UIColor.white.cgColor
    
    let shadowLayer = CAShapeLayer()
    shadowLayer.shadowColor = UIColor.black.cgColor
    shadowLayer.shadowOffset = CGSize(width: 0.0, height: 4.0)
    shadowLayer.shadowRadius = 6.0
    shadowLayer.shadowOpacity = 0.25
    shadowLayer.shadowPath = mask.path
    
    self.layer.insertSublayer(shadowLayer, at: 0)
    self.layer.insertSublayer(mask, at: 1)
    
    0 讨论(0)
  • 2020-11-22 08:14

    I make some changes to the code of daniel.gindi

    This is all you need to make it work.

    + (void)putView:(UIView*)view insideShadowWithColor:(UIColor*)color andBlur:         (CGFloat)blur andOffset:(CGSize)shadowOffset andOpacity:(CGFloat)shadowOpacity
    {
        CGRect shadowFrame = view.frame;
        UIView * shadow = [[UIView alloc] initWithFrame:shadowFrame];
        shadow.backgroundColor = [UIColor redColor];
        shadow.userInteractionEnabled = YES; // Modify this if needed
        shadow.layer.shadowColor = color.CGColor;
        shadow.layer.shadowOffset = shadowOffset;
        shadow.layer.shadowRadius = blur;
        shadow.layer.cornerRadius = view.layer.cornerRadius;
        shadow.layer.masksToBounds = NO;
        shadow.clipsToBounds = NO;
        shadow.layer.shadowOpacity = shadowOpacity;
        [view.superview insertSubview:shadow belowSubview:view];
    }
    
    0 讨论(0)
提交回复
热议问题