UIView with rounded corners and drop shadow?

前端 未结 30 2609
一整个雨季
一整个雨季 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:30

    Using Swift 4 and Xcode 9, this is a working example of rounding an ImageView with a drop shadow, and a border.

        //set dimensions and position of image (in this case, centered)
        let imageHeight: CGFloat = 150, imageWidth: CGFloat = 150
        let xPosition = (self.view.frame.width / 2) - (imageWidth / 2)
        let yPosition = (self.view.frame.height / 2) - (imageHeight / 2)
    
        //set desired corner radius
        let cornerRadius: CGFloat = 20
    
        //create container for the image
        let imageContainer = UIView(frame: CGRect(x: xPosition, y: yPosition, width: imageWidth, height: imageHeight))
    
        //configure the container
        imageContainer.clipsToBounds = false
        imageContainer.layer.shadowColor = UIColor.black.cgColor
        imageContainer.layer.shadowOpacity = 1
        imageContainer.layer.shadowOffset = CGSize(width: 3.0, height: 3.0)
        imageContainer.layer.shadowRadius = 5
        imageContainer.layer.shadowPath = UIBezierPath(roundedRect: imageContainer.bounds, cornerRadius: cornerRadius).cgPath
    
        //create imageView
        let imageView = UIImageView(frame: imageContainer.bounds)
    
        //configure the imageView
        imageView.clipsToBounds = true
        imageView.layer.cornerRadius = cornerRadius
        //add a border (if required)
        imageView.layer.borderColor = UIColor.black.cgColor
        imageView.layer.borderWidth = 1.0
        //set the image
        imageView.image = UIImage(named: "bird")
    
        //add the views to the superview
        view.addSubview(imageContainer)
        imageContainer.addSubview(imageView)
    

    If you want the image to be circular: (and shown without border)

    let cornerRadius = imageWidth / 2
    

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

    Shadow + Border + Corner Radius enter image description here

        scrollview.backgroundColor = [UIColor whiteColor]; 
        CALayer *ScrlViewLayer = [scrollview layer];
        [ScrlViewLayer setMasksToBounds:NO ];
        [ScrlViewLayer setShadowColor:[[UIColor lightGrayColor] CGColor]];
        [ScrlViewLayer setShadowOpacity:1.0 ];
        [ScrlViewLayer setShadowRadius:6.0 ];
        [ScrlViewLayer setShadowOffset:CGSizeMake( 0 , 0 )];
        [ScrlViewLayer setShouldRasterize:YES];
        [ScrlViewLayer setCornerRadius:5.0];
        [ScrlViewLayer setBorderColor:[UIColor lightGrayColor].CGColor];
        [ScrlViewLayer setBorderWidth:1.0];
        [ScrlViewLayer setShadowPath:[UIBezierPath bezierPathWithRect:scrollview.bounds].CGPath];
    
    0 讨论(0)
  • 2020-11-22 08:33

    The following worked best for me (this code lies in UIView extension, so self denotes some UIView to which we must add a shadow and round corner)

    - (void)addShadowViewWithCornerRadius:(CGFloat)radius {
    
    UIView *container = self.superview;
    
    if (!container) {
        return;
    }
    
    UIView *shadowView = [[UIView alloc] init];
    shadowView.translatesAutoresizingMaskIntoConstraints = NO;
    shadowView.backgroundColor = [UIColor lightGrayColor];
    shadowView.layer.cornerRadius = radius;
    shadowView.layer.masksToBounds = YES;
    
    [container addSubview:shadowView];
    [container bringSubviewToFront:shadowView];
    
    [container addConstraint:[NSLayoutConstraint constraintWithItem:shadowView
                                                          attribute:NSLayoutAttributeWidth
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:self
                                                          attribute:NSLayoutAttributeWidth
                                                         multiplier:1.0
                                                           constant:0.0]];
    [container addConstraint:[NSLayoutConstraint constraintWithItem:shadowView
                                                          attribute:NSLayoutAttributeLeading
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:self
                                                          attribute:NSLayoutAttributeLeading
                                                         multiplier:1.0
                                                           constant:2.0]];
    
    [container addConstraint:[NSLayoutConstraint constraintWithItem:shadowView
                                                          attribute:NSLayoutAttributeHeight
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:self
                                                          attribute:NSLayoutAttributeHeight
                                                         multiplier:1.0
                                                           constant:0.0]];
    [container addConstraint:[NSLayoutConstraint constraintWithItem:shadowView
                                                          attribute:NSLayoutAttributeTop
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:self
                                                          attribute:NSLayoutAttributeTop
                                                         multiplier:1.0
                                                           constant:2.0]];
    [container sendSubviewToBack:shadowView];
    }
    

    The main difference between this and other code samples is that this adds the shadow view as a sibling view (as against adding the current view as subview of shadow view), thereby eliminating the need to modify the existing view hierarchy in any way.

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

    You need to use two UIViews to achieve this. One UIView will work like shadow and other one will work for rounded border.

    Here is a code snippet a Class Method with a help of a protocol:

    @implementation UIMethods
    
    + (UIView *)genComposeButton:(UIViewController <UIComposeButtonDelegate> *)observer;
    {
        UIView *shadow = [[UIView alloc]init];
        shadow.layer.cornerRadius = 5.0;
        shadow.layer.shadowColor = [[UIColor blackColor] CGColor];
        shadow.layer.shadowOpacity = 1.0;
        shadow.layer.shadowRadius = 10.0;
        shadow.layer.shadowOffset = CGSizeMake(0.0f, -0.5f);
    
        UIButton *btnCompose = [[UIButton alloc]initWithFrame:CGRectMake(0, 0,60, 60)];
        [btnCompose setUserInteractionEnabled:YES];
        btnCompose.layer.cornerRadius = 30;
        btnCompose.layer.masksToBounds = YES;
        [btnCompose setImage:[UIImage imageNamed:@"60x60"] forState:UIControlStateNormal];
        [btnCompose addTarget:observer action:@selector(btnCompose_click:) forControlEvents:UIControlEventTouchUpInside];
        [shadow addSubview:btnCompose];
        return shadow;
    }
    

    In the code above btnCompose_click: will become a @required delegate method which will fire on the button click.

    And here I added a button to my UIViewController like this:

    UIView *btnCompose = [UIMethods genComposeButton:self];
    btnCompose.frame = CGRectMake(self.view.frame.size.width - 75,
                              self.view.frame.size.height - 75,
                              60, 60);
    [self.view addSubview:btnCompose];
    

    The result will look like this:

    enter image description here

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

    Well if you don't want to change your nibs and view hierarchy as suggested David C. this method will do it for you. To add rounded corners and shadow to your UIImageView just use this method, for example:

    [Utils roundCornersForImageView:myImageView withCornerRadius:6.0 
    andShadowOffset:2.0];
    

    (!) For performance reasons I don't think it is a good idea to use this code in something like UITableView, since this code changes view hierarchy. So I will suggest to change your nib and add a container view for shadow effect and use Davic C. code.

    + (void)roundCornersForImageView:(UIImageView *)imageView 
    withCornerRadius:(float)cornerRadius andShadowOffset:(float)shadowOffset
    {
        const float CORNER_RADIUS = cornerRadius;
        const float BORDER_WIDTH = 1.0; 
        const float SHADOW_OFFSET = shadowOffset;
        const float SHADOW_OPACITY = 0.8;
        const float SHADOW_RADIUS = 3.0;
    
        //Our old image now is just background image view with shadow
        UIImageView *backgroundImageView = imageView;
        UIView *superView = backgroundImageView.superview;
    
        //Make wider actual visible rect taking into account shadow
        //offset
        CGRect oldBackgroundFrame = backgroundImageView.frame;
        CGRect newBackgroundFrame = CGRectMake(oldBackgroundFrame.origin.x, oldBackgroundFrame.origin.y, oldBackgroundFrame.size.width + SHADOW_OFFSET, oldBackgroundFrame.size.height + SHADOW_OFFSET);
        [backgroundImageView removeFromSuperview];
        backgroundImageView.frame = newBackgroundFrame;        
    
        //Make new UIImageView with rounded corners and put our old image
        CGRect frameForRoundedImageView = CGRectMake(0, 0, oldBackgroundFrame.size.width, oldBackgroundFrame.size.height);
        UIImageView *roundedImageView = [[UIImageView alloc]initWithFrame:frameForRoundedImageView];
        roundedImageView.image = imageView.image;
        [roundedImageView.layer setCornerRadius:CORNER_RADIUS];
        [roundedImageView.layer setBorderColor:[UIColor lightGrayColor].CGColor];        
        [roundedImageView.layer setBorderWidth:BORDER_WIDTH]; 
        [roundedImageView.layer setMasksToBounds:YES];
    
        //Set shadow preferences
        [backgroundImageView setImage:nil];
        [backgroundImageView.layer setShadowColor:[UIColor blackColor].CGColor];
        [backgroundImageView.layer setShadowOpacity:SHADOW_OPACITY];
        [backgroundImageView.layer setShadowRadius:SHADOW_RADIUS];
        [backgroundImageView.layer setShadowOffset:CGSizeMake(SHADOW_OFFSET, SHADOW_OFFSET)];   
    
        //Add out two image views back to the view hierarchy.
        [backgroundImageView addSubview:roundedImageView];
        [superView addSubview:backgroundImageView];   
    }    
    
    0 讨论(0)
  • 2020-11-22 08:37

    The answer provided by Evan Mulawski will work perfectly. The catch is that you have to set the background color for the view to clearColor and the masksToBounds property to NO.

    You can set whatever color you want for the view, set it like

    v.layer.backgroundColor = your color;
    

    Hope this helps..

    0 讨论(0)
提交回复
热议问题