带圆角的UITextField内部阴影

7
我想实现这种 UITextField 的设计:

enter image description here

在 Zeplin 中,这里是阴影的属性:

enter image description here

我尝试过什么?
override func layoutSubviews() {
    super.layoutSubviews()
    self.layer.cornerRadius = self.frame.size.height/2
    self.addInnerShadow()
}


private func addInnerShadow() {
    let innerShadow = CALayer()
    innerShadow.frame = bounds
    // Shadow path (1pt ring around bounds)
    let path = UIBezierPath(rect: innerShadow.bounds.insetBy(dx: -1, dy: -1))
    let cutout = UIBezierPath(rect: innerShadow.bounds).reversing()
    path.append(cutout)
    innerShadow.shadowPath = path.cgPath
    innerShadow.masksToBounds = true
    // Shadow properties
    innerShadow.shadowColor = UIColor.black.cgColor
    innerShadow.shadowOffset = CGSize(width: 0, height: 3)
    innerShadow.shadowOpacity = 0.05
    innerShadow.shadowRadius = 3
    innerShadow.cornerRadius = self.frame.size.height/2
    layer.addSublayer(innerShadow)
}

结果:

在此输入图像描述

更新:

override func layoutSubviews() {
     super.layoutSubviews()
     self.layer.cornerRadius = self.frame.size.height/2
     self.addInnerShadow()
 }


private func addInnerShadow() {
    let innerShadow = CALayer()
    innerShadow.frame = bounds
    // Shadow path (1pt ring around bounds)
    let path = UIBezierPath(roundedRect: innerShadow.bounds.insetBy(dx: -1, dy: -1), cornerRadius: self.frame.size.height/2)
    let cutout = UIBezierPath(rect: innerShadow.bounds).reversing()
    path.append(cutout)
    innerShadow.shadowPath = path.cgPath
    innerShadow.masksToBounds = true
    // Shadow properties
    innerShadow.shadowColor = UIColor.black.cgColor
    innerShadow.shadowOffset = CGSize(width: 0, height: 3)
    innerShadow.shadowOpacity = 0.05
    innerShadow.shadowRadius = 3
    //innerShadow.cornerRadius = self.frame.size.height/2
    layer.addSublayer(innerShadow)
}

结果:

在此输入图片描述

由于路径仍然是矩形的,角半径导致了问题,阴影看起来不同。


在一个带有阴影的图层上设置 cornerRadius 是无法生效的。相反,您需要相应地创建路径:https://developer.apple.com/documentation/uikit/uibezierpath/1624356-init - David Ganster
@DavidGanster 我已经尝试过了,但它并没有起作用。 - iOSGeek
到底是什么出了问题?要完全复制内部阴影,使其看起来与设计稿完全相同确实非常困难(我建议使用可拉伸的图片),但是使用圆角路径来创建阴影绝对可行。 - David Ganster
@DavidGanster,请查看我的更新。 - iOSGeek
你的抠图似乎与你想要的相反 - 只有角落有阴影,而其他地方则没有。 - David Ganster
2个回答

21

只需使用圆角矩形路径:

private func addInnerShadow() {
    let innerShadow = CALayer()
    innerShadow.frame = bounds
    
    // Shadow path (1pt ring around bounds)
    let radius = self.frame.size.height/2
    let path = UIBezierPath(roundedRect: innerShadow.bounds.insetBy(dx: -1, dy:-1), cornerRadius:radius)
    let cutout = UIBezierPath(roundedRect: innerShadow.bounds, cornerRadius:radius).reversing()
    
    
    path.append(cutout)
    innerShadow.shadowPath = path.cgPath
    innerShadow.masksToBounds = true
    // Shadow properties
    innerShadow.shadowColor = UIColor.black.cgColor
    innerShadow.shadowOffset = CGSize(width: 0, height: 3)
    innerShadow.shadowOpacity = 0.15
    innerShadow.shadowRadius = 3
    innerShadow.cornerRadius = self.frame.size.height/2
    layer.addSublayer(innerShadow)
}

这里输入图片描述


0
为了实现这个效果,我添加了一个UIImageView,并将图像作为阴影文本单元格输入,然后在UIImageView上放置了一个带有透明背景的标签,以便您可以通过文本看到阴影图像。所有这些都是使用Storyboard完成的,因此我没有代码可展示,也不允许上传图像。希望这可以帮助到您。

请分享代码或更多的解释。请记住,您正在为未来的读者回答问题,这些人可能不知道您建议的原因。 - Muhammad Dyas Yaskur
希望这有意义。 - Katie Lewis

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