我在一个应用程序上工作了几年,收到了一个简单的设计请求:在UIView上圆角并添加投影。做以下所给的事
我想要一个自定义的UIView…:我只是想要一个空白的白色视图与圆角和光滴阴影(没有照明效果)。我可以逐个执行这些操作,但通常会发生clipToBounds/maskToBounds冲突。
我在一个应用程序上工作了几年,收到了一个简单的设计请求:在UIView上圆角并添加投影。做以下所给的事
我想要一个自定义的UIView…:我只是想要一个空白的白色视图与圆角和光滴阴影(没有照明效果)。我可以逐个执行这些操作,但通常会发生clipToBounds/maskToBounds冲突。
当前回答
下面的方法最适合我 (这段代码位于UIView扩展中,因此self表示一些我们必须添加阴影和圆角的UIView)
- (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];
}
此代码与其他代码示例之间的主要区别在于,它将阴影视图添加为兄弟视图(而不是将当前视图添加为阴影视图的子视图),从而消除了以任何方式修改现有视图层次结构的需要。
其他回答
下面的方法最适合我 (这段代码位于UIView扩展中,因此self表示一些我们必须添加阴影和圆角的UIView)
- (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];
}
此代码与其他代码示例之间的主要区别在于,它将阴影视图添加为兄弟视图(而不是将当前视图添加为阴影视图的子视图),从而消除了以任何方式修改现有视图层次结构的需要。
我写了这个UIView分类方法来解决这个问题,使用单独的视图来表示阴影和角的半径。
-(UIView *)shadowedWrapViewWithBounds:(CGRect)bounds {
UIView *baseView = [[UIView alloc] init];
baseView.bounds = bounds;
baseView.backgroundColor = [UIColor clearColor];
baseView.layer.shadowColor = [UIColor blackColor].CGColor;
baseView.layer.shadowOffset = CGSizeMake(0, 0);
baseView.layer.shadowOpacity = 0.7;
baseView.layer.shadowRadius = 4.0;
// improve performance
baseView.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:baseView.bounds cornerRadius:4].CGPath;
baseView.layer.shouldRasterize = YES;
baseView.layer.rasterizationScale = [UIScreen mainScreen].scale;
[baseView addSubview:self];
//use Masonry autolayout, self can set corner radius
[self makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(baseView);
}];
return baseView;
}
Swift 4解决方案,使UICollectionViewCell圆形和添加阴影,没有任何扩展和并发症:)
注意:对于简单的视图,例如按钮。请看这篇文章中的@suragch的回答。 https://stackoverflow.com/a/34984063/7698092。按钮测试成功
以防有人还在努力使角落圆润,同时添加阴影。虽然这个解决方案适用于UICollectionViewCell,但它可以推广到任何视图。
这个技巧对我来说很有效,不需要做任何扩展和所有复杂的事情。我正在使用storyBoard。
技术
你必须在storyBoard的UICollectionViewCell中添加一个UIView(让我们说它是“containerView”),并在这个containerView中添加所有必需的视图(按钮,图像等)。 见截图。
连接containerView的出口。在CellforItemAtIndexPath委托函数中添加以下代码行。
//adds shadow to the layer of cell
cell.layer.cornerRadius = 3.0
cell.layer.masksToBounds = false
cell.layer.shadowColor = UIColor.black.cgColor
cell.layer.shadowOffset = CGSize(width: 0, height: 0)
cell.layer.shadowOpacity = 0.6
//makes the cell round
let containerView = cell.containerView!
containerView.layer.cornerRadius = 8
containerView.clipsToBounds = true
输出
查看模拟器截图
我在UIView中创建了一个helper
@interface UIView (Helper)
- (void)roundCornerswithRadius:(float)cornerRadius
andShadowOffset:(float)shadowOffset;
@end
你可以这样叫它
[self.view roundCornerswithRadius:5 andShadowOffset:5];
这是实现
- (void)roundCornerswithRadius:(float)cornerRadius
andShadowOffset:(float)shadowOffset
{
const float CORNER_RADIUS = cornerRadius;
const float SHADOW_OFFSET = shadowOffset;
const float SHADOW_OPACITY = 0.5;
const float SHADOW_RADIUS = 3.0;
UIView *superView = self.superview;
CGRect oldBackgroundFrame = self.frame;
[self removeFromSuperview];
CGRect frameForShadowView = CGRectMake(0, 0, oldBackgroundFrame.size.width, oldBackgroundFrame.size.height);
UIView *shadowView = [[UIView alloc] initWithFrame:frameForShadowView];
[shadowView.layer setShadowOpacity:SHADOW_OPACITY];
[shadowView.layer setShadowRadius:SHADOW_RADIUS];
[shadowView.layer setShadowOffset:CGSizeMake(SHADOW_OFFSET, SHADOW_OFFSET)];
[self.layer setCornerRadius:CORNER_RADIUS];
[self.layer setMasksToBounds:YES];
[shadowView addSubview:self];
[superView addSubview:shadowView];
}
这对我很管用。窍门是将背景颜色从主视图移到图层中。
CALayer *layer = view.layer;
layer.cornerRadius = 15.0f;
layer.masksToBounds = NO;
layer.shadowOffset = CGSizeMake(0, 3);
layer.shadowColor = [[UIColor blackColor] CGColor];
layer.shadowRadius = 2.0f;
layer.shadowOpacity = 0.35f;
layer.shadowPath = [[UIBezierPath bezierPathWithRoundedRect:layer.bounds cornerRadius:layer.cornerRadius] CGPath];
CGColorRef bColor = view.backgroundColor.CGColor;
view.backgroundColor = nil;
layer.backgroundColor = bColor ;