UIView 圆角和阴影

17

我想展示一个带有圆角和阴影的UIView。但问题在于maskToBounds属性只能用于其中一种情况。

如果maskToBounds为YES,则显示圆角,如果为NO,则显示阴影。这里是实现代码,但它只显示带有圆角而没有阴影:

[self.view setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"blue_gradient.jpeg"]]];


    self.view.layer.masksToBounds = YES; 
    self.view.layer.opaque = NO; 
    self.view.layer.cornerRadius = 15.0f; 


    self.view.layer.shadowColor = [UIColor blackColor].CGColor;
    self.view.layer.shadowRadius = 5.0; 
    self.view.layer.shadowOffset = CGSizeMake(3.0, 3.0);
    self.view.layer.shadowOpacity = 0.9f;

想法!

注意:我已经阅读并实现了以下线程中的代码,但它没有起作用:UIView with rounded corners and drop shadow?

更新1:

我尝试创建两个单独的视图。一个表示半径,一个表示阴影。问题在于它会在半径视图顶部创建阴影,如下面的截图所示:

enter image description here

H

ere is the code: 

 self.view.layer.masksToBounds = YES; 
    self.view.layer.opaque = NO; 
    self.view.layer.cornerRadius = 15.0f; 
   // self.view.backgroundColor = [UIColor clearColor];
    self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"blue_gradient.jpeg"]];
//
    UIView *shadowView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    shadowView.layer.shadowColor = [UIColor blackColor].CGColor;
    shadowView.layer.shadowRadius = 2.0; 
    shadowView.backgroundColor = [UIColor clearColor];
    shadowView.layer.shadowOffset = CGSizeMake(3.0, 3.0);
    shadowView.layer.shadowOpacity = 0.9f;
    shadowView.layer.shadowPath = [UIBezierPath 
                                                                   bezierPathWithRect:CGRectMake(0, 0, 100, 100)].CGPath;

    [self.view addSubview:shadowView];

更新2:

倒角仍然不起作用,没有创建任何圆角。

UIView *roundCornerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    roundCornerView.layer.masksToBounds = YES; 
    roundCornerView.layer.opaque = NO; 
    roundCornerView.layer.cornerRadius = 15.0f; 

    self.view.layer.shadowColor = [UIColor blackColor].CGColor;
    self.view.layer.shadowRadius = 2.0; 
    //self.view.backgroundColor = [UIColor clearColor];
    self.view.layer.shadowOffset = CGSizeMake(3.0, 3.0);
    self.view.layer.shadowOpacity = 0.9f;
    self.view.layer.shadowPath = [UIBezierPath 
                                                                   bezierPathWithRect:CGRectMake(0, 0, 100, 100)].CGPath;

    [self.view addSubview:roundCornerView];

解决方案:

 UIView *roundCornerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    roundCornerView.layer.masksToBounds = YES; 
    roundCornerView.layer.opaque = NO; 
    roundCornerView.layer.cornerRadius = 15.0f; 

    roundCornerView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"blue_gradient.jpeg"]];

    self.view.layer.shadowColor = [UIColor blackColor].CGColor;
    self.view.layer.shadowRadius = 2.0; 
    self.view.backgroundColor = [UIColor clearColor];
    self.view.layer.shadowOffset = CGSizeMake(3.0, 3.0);
    self.view.layer.shadowOpacity = 0.9f;
    //self.view.layer.shadowPath = [UIBezierPath 
      //                                                             bezierPathWithRect:CGRectMake(0, 0, 100, 100)].CGPath;

    [self.view addSubview:roundCornerView];

可能是重复的问题:如何创建带有圆角和阴影的UIView? - Evan Mulawski
1
不行!已经查看了那个问题并尝试了那种方法,但它没有起作用。 - azamsharp
这里有一个hackish的想法,你可以尝试将边框宽度设置为20,使用UIColor clearColor。 - Nate Flink
清除颜色不起作用,因为它会显示在UI视图下面的地图。 - azamsharp
在iOS 11中,不再需要使用子视图方法,因为它有一个新的CALayer属性专门用于遮罩圆角:https://stackoverflow.com/a/49559042/7450 - jlew
3个回答

11

创建两个视图。 一个带有投影(不要忘记设置shadowPath),其中您添加了一个具有cornerRadiusmaskToBounds的子视图。


你需要反转这两个视图,剪裁视图必须成为阴影视图的子视图。 - iSofTom
实际上有角落,但你无法看到它们的原因有两个。第一,因为您剪辑视图中没有内容,第二,因为阴影路径是矩形而不是圆角矩形! - iSofTom

10

原有答案没有包含任何代码,所以这里提供了一个Swift示例(请参考原问题查看原作者使用的Obj-C解决方案)。

enter image description here

和原有答案一样,这个解决方案使用了分别用于阴影和圆角半径的不同视图。

// add the shadow to the base view
baseView.backgroundColor = UIColor.clear
baseView.layer.shadowColor = UIColor.black.cgColor
baseView.layer.shadowOffset = CGSize(width: 3, height: 3)
baseView.layer.shadowOpacity = 0.7
baseView.layer.shadowRadius = 4.0

// improve performance
baseView.layer.shadowPath = UIBezierPath(roundedRect: baseView.bounds, cornerRadius: 10).cgPath
baseView.layer.shouldRasterize = true
baseView.layer.rasterizationScale = UIScreen.main.scale

// add the border to subview
let borderView = UIView()
borderView.frame = baseView.bounds
borderView.layer.cornerRadius = 10
borderView.layer.borderColor = UIColor.black.cgColor
borderView.layer.borderWidth = 1.0
borderView.layer.masksToBounds = true
baseView.addSubview(borderView)

// add any other subcontent that you want clipped
let otherSubContent = UIImageView()
otherSubContent.image = UIImage(named: "lion")
otherSubContent.frame = borderView.bounds
borderView.addSubview(otherSubContent)

我的完整答案在这里


如果在Storyboard中添加视图,应该如何操作?我需要使用3个视图吗?还是不可能实现? - Prashant Tukadiya
@MikeAlter,虽然我没有在Storyboard中完成它,但我认为使用三个视图是可能的。如果属性检查器中没有必要的属性,请查看使用用户定义的运行时属性 - Suragch

1
您可以通过应用以下方法在单个视图中完成它:
1. 首先添加一个圆角。
yourview.layer.cornerRadius = 5.0

2. 调用下面的函数

shadowToView(view : yourview)


func shadowToView(view : UIView){
    view.layer.shadowOffset = CGSize(width: 0, height: 3)
    view.layer.shadowOpacity = 0.6
    view.layer.shadowRadius = 3.0
    view.layer.shadowColor = UIColor.darkGray.cgColor
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接