我必须创建一个自定义 UIView
,它将具有圆角,边框和阴影,并且它的 drawRect()
方法被覆盖以提供自定义绘图代码,其中几条直线被绘制到视图中(我需要在这里使用快速,轻量级的方法因为可以呈现许多这些视图) .
一旦我在视图类中覆盖 drawRect()
(即使其中没有任何自定义代码),问题我就不再应用于圆角了 . 请参阅附图中的差异:
在视图控制器中我使用以下代码:
view.layer.cornerRadius = 10;
view.layer.masksToBounds = true;
view.layer.borderColor = UIColor.grayColor().CGColor;
view.layer.borderWidth = 0.5;
view.layer.contentsScale = UIScreen.mainScreen().scale;
view.layer.shadowColor = UIColor.blackColor().CGColor;
view.layer.shadowOffset = CGSizeZero;
view.layer.shadowRadius = 5.0;
view.layer.shadowOpacity = 0.5;
view.layer.masksToBounds = false;
view.clipsToBounds = false;
在被覆盖的 drawContext()
中,我会使用类似的东西:
var context:CGContext = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, UIColor.redColor().CGColor);
// Draw them with a 2.0 stroke width so they are a bit more visible.
CGContextSetLineWidth(context, 2.0);
CGContextMoveToPoint(context, 0.0, 0.0); //start at this point
CGContextAddLineToPoint(context, 20.0, 20.0); //draw to this point
CGContextStrokePath(context);
但如上所述,即使没有添加此代码,也会出现阴影问题 .
除了这种与圆角和阴影兼容的方法之外,还有其他/更好的方法将轻量元素绘制到视图上吗?我不想在视图中添加任何不必要的额外视图或图像上下文,因为它们需要轻巧且高效 .
16 回答
这是一个棘手的问题 .
UIView
的clipsToBounds
是获得圆角的必要条件 . 但是CALayer
的masksToBounds
必须是false
所以阴影是可见的 . 不知何故,如果drawRect
没有被覆盖,一切都有效,但实际上它不应该被覆盖 .解决方案是创建一个superview来提供阴影(在下面的演示中,这是
shadowView
) . 您可以在Playground中测试以下内容:结果:
我给UIView写了一个小扩展来管理圆角和阴影 . 由于变量是@IBInspectable,所有内容都可以直接在故事板中设置!
这就是它在故事板中的样子:
结果:
有一个要求:不要在视图上(在代码中或在IB中)触摸clipToBounds或在图层上触摸masksToBound .
注意:一个不起作用的情况:tableViews . 由于UITableView会在引擎盖下自动触发
clipToBounds
,因此我们不能有阴影 .编辑:正如Claudia Fitero恰当地注意到的那样,你需要在视图周围留下一个小填充,你要添加一个阴影,否则阴影将不可见 . 2px-padding一般就足够了(取决于你的阴影半径) .
阴影从视图层内的任何内容中删除 . 禁用剪裁时,整个图层矩形将被默认
backgroundColor
填充,因此阴影也变为矩形 . 而不是用圆形蒙版剪裁它只是使图层的内容四舍五入,自己绘制它们 . 并且layer
的边界是围绕它的边界绘制的,所以你也需要自己绘制它 .例如,在
backgroundColor
setter中将实际背景颜色设置为clearColor
,并使用drawRect
中的传递颜色绘制圆角矩形 .在下面的示例中,我将属性声明为
IBInspectable
,将整个类声明为IBDesignable
,因此可以在storyboard中设置所有内容 . 这样,您甚至可以使用默认的背景选择器来更改圆角矩形颜色 .斯威夫特
斯威夫特3
Objective-C .h
Objective-C .m
Result
这是Hodit's答案的swift3版本,我不得不使用它并在这里找到并对XCode 8进行了一般性修正 . 就像魅力一样!
斯威夫特3
我做了一个UIView扩展,它与Mundi提出的基本相同的想法:
使用:
SWIFT 3 Solution
改编自Mundi的答案
我发现以下链接有助于理解设置Drophadow:
How to add a shadow to a UIView
要为UIVIEW设置圆角,只需在界面构建器中设置
layer.cornerRadius
值,请检查屏幕截图 .解决方案似乎比问题所暗示的要容易得多 . 我有一个观点,并使用@ Hodit的答案的核心部分来实现它 . 这就是你真正需要的:
请注意,这不会剪辑子视图 . 在视图中位于0,0的任何内容都将与可见的左上角圆角重叠 .
试试这个对我有用......
在斯威夫特 . 对我有用的是添加:
所以,完整的代码是:
除了Frederic Adda的解决方案之外,不要忘记将具有填充阴影的视图定位到超视图,其中可以绘制阴影 . 否则阴影将被剪掉 . 我在我的自定义单元格中犯了这个错误,并认为解决方案是错误的,直到我添加了8px的填充 .
这是我的解决方案 . 如果您有多种类型的视图,如UIView,UIControl,UITableView等,并且不想创建每个类的子类,或者您想要对代码进行最小的更改来添加此效果,那么这可能就是您的意思正在找 .
Objective-C.h
Objective-C.m
我使用此扩展名为
UIView
:这是一个较旧的问题,但我会在您的自定义绘制方法中完成所有操作,如下所示 .
我通常会这样做,如果我知道我想在我的圆形视图中应用阴影(这当然意味着我不想使用
masksToBounds
)您也不必在层次结构中添加额外的“阴影视图” .
在Swift 4.1中 . 为了制作UIView的圆角,我创建了UIView的扩展,如下所示 .
您可以将此功能用于所有视图 .