简体   繁体   English

如何为透明的 UIView 添加阴影?

[英]How to add shadow to a transparent UIView?

How can I reproduce this shadowing?我怎样才能重现这种阴影? My problem, that if I use high alpha color or clearColor, there is no drop shadow, if I use low alpha color, I can't see the drop shadow under the plate.我的问题,如果我使用高 alpha 颜色或 clearColor,则没有阴影,如果我使用低 alpha 颜色,我看不到板下的阴影。 As the level of the volume is changing (colorful part) the shadow is moving also, so it is not pure Photoshop.随着音量的变化(彩色部分)阴影也在移动,所以它不是纯粹的Photoshop。

在此处输入图片说明

try something using thoses properies of your view.尝试使用您的观点的那些属性。 it might end up with something它可能会以某种方式结束

    view.layer.shadowColor = [UIColor colorWithWhite:.5 alpha:1].CGColor;
    view.layer.shadowRadius = 4.0f;
    view.layer.shadowPath = CGPathCreateWithRect(CGRectMake(0, 0, 50, 50), NULL);
    view.layer.shadowOpacity = 1.0f;
    view.layer.shadowOffset = CGSizeMake(1, 1);

it's leaking by the way should CGPathRelease(rect) at the end sorry.顺便说一句,如果 CGPathRelease(rect) 最后抱歉,它会泄漏。

After searching and not finding an answer to this question I wrote the following extension in Swift 5:在搜索并没有找到这个问题的答案后,我在 Swift 5 中编写了以下扩展:

extension UIView {
    func makeClearViewWithShadow(
        cornderRadius: CGFloat,
        shadowColor: CGColor,
        shadowOpacity: Float,
        shadowRadius: CGFloat) {

        self.frame = self.frame.insetBy(dx: -shadowRadius * 2,
                                        dy: -shadowRadius * 2)
        self.backgroundColor = .clear
        let shadowView = UIView(frame: CGRect(
            x: shadowRadius * 2,
            y: shadowRadius * 2,
            width: self.frame.width - shadowRadius * 4,
            height: self.frame.height - shadowRadius * 4))
        shadowView.backgroundColor = .black
        shadowView.layer.cornerRadius = cornderRadius
        shadowView.layer.borderWidth = 1.0
        shadowView.layer.borderColor = UIColor.clear.cgColor

        shadowView.layer.shadowColor = shadowColor
        shadowView.layer.shadowOpacity = shadowOpacity
        shadowView.layer.shadowRadius = shadowRadius
        shadowView.layer.masksToBounds = false
        self.addSubview(shadowView)

        let p:CGMutablePath = CGMutablePath()
        p.addRect(self.bounds)
        p.addPath(UIBezierPath(roundedRect: shadowView.frame, cornerRadius: shadowView.layer.cornerRadius).cgPath)

        let s = CAShapeLayer()
        s.path = p
        s.fillRule = CAShapeLayerFillRule.evenOdd

       self.layer.mask = s
    }
}

Usage Example:用法示例:

myView.makeClearViewWithShadow(cornderRadius: 20, shadowColor: UIColor.black.cgColor, shadowOpacity: 0.5, shadowRadius: 30)

You will have two images one is the colorful image, and the other will be the shadow of it the shadow will expand and increase in width with the expansion of the colorful part您将有两个图像,一个是彩色图像,另一个是它的阴影阴影会随着彩色部分的扩展而扩大并增加宽度

There is no native way to do what you are asking,没有原生的方式来做你所要求的,

I used an UIImageView to provide the shadow.我使用 UIImageView 来提供阴影。 I created an image of 1 pixel wide, by 12 pixels high.我创建了一个 1 像素宽、12 像素高的图像。 The image was black, but the alpha was a gradient from 0.5 at the top to 0.0 at the bottom eg.图像是黑色的,但 alpha 是从顶部的 0.5 到底部的 0.0 的渐变,例如。 RGBA 1.0,1.0,1.0,0.5 -> 1.0,1.0,1.0,0.0 - I then placed the UIImageView just below the view needing the shadow, and stretched it horizontally across the width of the view. RGBA 1.0,1.0,1.0,0.5 -> 1.0,1.0,1.0,0.0 - 然后我将 UIImageView 放在需要阴影的视图正下方,并在视图的宽度上水平拉伸它。 I have also used this when I needed to change the intensity of the shadow when a scroll view below is scrolling, by changing the UIImageView.alpha value当我需要在下面的滚动视图滚动时更改阴影的强度时,我也使用了它,方法是更改​​ UIImageView.alpha 值

My solution was to subclass UIView.我的解决方案是继承 UIView。 It works even if view gets resized.即使视图被调整大小它也能工作。

import UIKit

class ShadowOutsideView: UIView {
  let color: CGColor
  let opacity: Float
  let radius: CGFloat
  let offset: CGSize
  let shadowView = UIView()
  
  init(
    color: CGColor,
    opacity: Float,
    radius: CGFloat,
    offset: CGSize
  ) {
    self.color = color
    self.opacity = opacity
    self.radius = radius
    self.offset = offset
    super.init(frame: CGRect.zero)
    shadowView.frame = bounds
    shadowView.backgroundColor = .black
    shadowView.layer.shadowColor = color
    shadowView.layer.shadowOpacity = opacity
    shadowView.layer.shadowRadius = radius
    shadowView.layer.shadowOffset = offset
    shadowView.layer.masksToBounds = false
    self.addSubview(shadowView)
    
  }
  
  override func layoutSubviews() {
    shadowView.frame = bounds
    let inset = -(max(abs(offset.width), abs(offset.height))+radius) - 10 
    // - 10, had to put 10px extra otherwise it would cut shadow
    let maskFrame = bounds.inset(by: UIEdgeInsets(top: inset, left: inset, bottom: inset, right: inset))
    let p = CGMutablePath()
    p.addRect(maskFrame)
    p.addRect(bounds)
    let s = CAShapeLayer()
    s.path = p
    s.fillRule = .evenOdd
    shadowView.layer.mask = s
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM