我擡頭看,但我無法找到如何將內部陰影添加到UIView,只有頂部(從上到下)Swift。什麼是在Swift中添加內圈的最佳方式?將內部陰影添加到UIView頂部
編輯:我發現了一些問題&在SO上的答案,但他們要麼在obj-c或看起來如此複雜。我只是在尋找一個更SWIFTY的方式,如果有任何
我想達到的目標:
我擡頭看,但我無法找到如何將內部陰影添加到UIView,只有頂部(從上到下)Swift。什麼是在Swift中添加內圈的最佳方式?將內部陰影添加到UIView頂部
編輯:我發現了一些問題&在SO上的答案,但他們要麼在obj-c或看起來如此複雜。我只是在尋找一個更SWIFTY的方式,如果有任何
我想達到的目標:
使用下列庫:
https://github.com/nlampi/UIView-InnerShadow
// Add a shadow to the top of the view only
[exampleView addInnerShadowWithRadius:3.0f
andColor:[UIColor colorWithWhite:0 alpha:0.45f]
inDirection:NLInnerShadowDirectionTop];
我已經盡我所能將庫擴展名轉換爲Swift(這是未經測試的,因此我不能保證它能正常工作)。它應該讓你在正確的軌道上。
import UIKit
extension UIView {
struct NLInnerShadowDirection: OptionSetType {
let rawValue: Int
static let None = NLInnerShadowDirection(rawValue: 0)
static let Left = NLInnerShadowDirection(rawValue: 1 << 0)
static let Right = NLInnerShadowDirection(rawValue: 1 << 1)
static let Top = NLInnerShadowDirection(rawValue: 1 << 2)
static let Bottom = NLInnerShadowDirection(rawValue: 1 << 3)
static let All = NLInnerShadowDirection(rawValue: 15)
}
func removeInnerShadow() {
for view in self.subviews {
if (view.tag == 2639) {
view.removeFromSuperview()
break
}
}
}
func addInnerShadow() {
let c = UIColor()
let color = c.colorWithAlphaComponent(0.5)
self.addInnerShadowWithRadius(3.0, color: color, inDirection: NLInnerShadowDirection.All)
}
func addInnerShadowWithRadius(radius: CGFloat, andAlpha: CGFloat) {
let c = UIColor()
let color = c.colorWithAlphaComponent(alpha)
self.addInnerShadowWithRadius(radius, color: color, inDirection: NLInnerShadowDirection.All)
}
func addInnerShadowWithRadius(radius: CGFloat, andColor: UIColor) {
self.addInnerShadowWithRadius(radius, color: andColor, inDirection: NLInnerShadowDirection.All)
}
func addInnerShadowWithRadius(radius: CGFloat, color: UIColor, inDirection: NLInnerShadowDirection) {
self.removeInnerShadow()
let shadowView = self.createShadowViewWithRadius(radius, andColor: color, direction: inDirection)
self.addSubview(shadowView)
}
func createShadowViewWithRadius(radius: CGFloat, andColor: UIColor, direction: NLInnerShadowDirection) -> UIView {
let shadowView = UIView(frame: CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height))
shadowView.backgroundColor = UIColor.clearColor()
shadowView.tag = 2639
let colorsArray: Array = [ andColor.CGColor, UIColor.clearColor().CGColor ]
if direction.contains(.Top) {
let xOffset: CGFloat = 0.0
let topWidth = self.bounds.size.width
let shadow = CAGradientLayer()
shadow.colors = colorsArray
shadow.startPoint = CGPointMake(0.5, 0.0)
shadow.endPoint = CGPointMake(0.5, 1.0)
shadow.frame = CGRectMake(xOffset, 0, topWidth, radius)
shadowView.layer.insertSublayer(shadow, atIndex: 0)
}
if direction.contains(.Bottom) {
let xOffset: CGFloat = 0.0
let bottomWidth = self.bounds.size.width
let shadow = CAGradientLayer()
shadow.colors = colorsArray
shadow.startPoint = CGPointMake(0.5, 1.0)
shadow.endPoint = CGPointMake(0.5, 0.0)
shadow.frame = CGRectMake(xOffset, self.bounds.size.height - radius, bottomWidth, radius)
shadowView.layer.insertSublayer(shadow, atIndex: 0)
}
if direction.contains(.Left) {
let yOffset: CGFloat = 0.0
let leftHeight = self.bounds.size.height
let shadow = CAGradientLayer()
shadow.colors = colorsArray
shadow.frame = CGRectMake(0, yOffset, radius, leftHeight)
shadow.startPoint = CGPointMake(0.0, 0.5)
shadow.endPoint = CGPointMake(1.0, 0.5)
shadowView.layer.insertSublayer(shadow, atIndex: 0)
}
if direction.contains(.Right) {
let yOffset: CGFloat = 0.0
let rightHeight = self.bounds.size.height
let shadow = CAGradientLayer()
shadow.colors = colorsArray
shadow.frame = CGRectMake(self.bounds.size.width - radius, yOffset, radius, rightHeight)
shadow.startPoint = CGPointMake(1.0, 0.5)
shadow.endPoint = CGPointMake(0.0, 0.5)
shadowView.layer.insertSublayer(shadow, atIndex: 0)
}
return shadowView
}
}
我用Objective-C實現了內部陰影到UIView。我嘗試將代碼轉換爲swift。請原諒我的可憐的迅速語法
您可以在UIView.didMoveToSuperview撥打以下功能
func drawShadow() {
if nil == self.shadowLayer {
let size = self.frame.size
self.clipsToBounds = true
let layer: CALayer = CALayer()
layer.backgroundColor = UIColor.lightGrayColor().CGColor
layer.position = CGPointMake(size.width/2, -size.height/2 + 0.5)
layer.bounds = CGRectMake(0, 0, size.width, size.height)
layer.shadowColor = UIColor.darkGrayColor().CGColor
layer.shadowOffset = CGSizeMake(0.5, 0.5)
layer.shadowOpacity = 0.8
layer.shadowRadius = 5.0
self.shadowLayer = layer
self.layer.addSublayer(layer)
}
}
迄今爲止最好的答案。恕我直言。其他答案使用漸變,這不是在Core Graphics中繪製陰影的方式。 – beyowulf
@beyowulf感謝您糾正我的代碼。 –
'self.shadowLayer'從哪裏來? –
下面是我掀起了一個純粹的斯威夫特版本:
public class EdgeShadowLayer: CAGradientLayer {
public enum Edge {
case Top
case Left
case Bottom
case Right
}
public init(forView view: UIView,
edge: Edge = Edge.Top,
shadowRadius radius: CGFloat = 20.0,
toColor: UIColor = UIColor.white,
fromColor: UIColor = UIColor.black) {
super.init()
self.colors = [fromColor.cgColor, toColor.cgColor]
self.shadowRadius = radius
let viewFrame = view.frame
switch edge {
case .Top:
startPoint = CGPoint(x: 0.5, y: 0.0)
endPoint = CGPoint(x: 0.5, y: 1.0)
self.frame = CGRect(x: 0.0, y: 0.0, width: viewFrame.width, height: shadowRadius)
case .Bottom:
startPoint = CGPoint(x: 0.5, y: 1.0)
endPoint = CGPoint(x: 0.5, y: 0.0)
self.frame = CGRect(x: 0.0, y: viewFrame.height - shadowRadius, width: viewFrame.width, height: shadowRadius)
case .Left:
startPoint = CGPoint(x: 0.0, y: 0.5)
endPoint = CGPoint(x: 1.0, y: 0.5)
self.frame = CGRect(x: 0.0, y: 0.0, width: shadowRadius, height: viewFrame.height)
case .Right:
startPoint = CGPoint(x: 1.0, y: 0.5)
endPoint = CGPoint(x: 0.0, y: 0.5)
self.frame = CGRect(x: viewFrame.width - shadowRadius, y: 0.0, width: shadowRadius, height: viewFrame.height)
}
}
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
要使用它,
let topShadow = EdgeShadowLayer(forView: targetView, edge: .Top)
view.layer.addSublayer(topShadow)
請注意,它默認爲20像素深的黑白漸變。
可以在https://github.com/jrtibbetts/Tenebrae找到完整的代碼,其示例UIViewController
可讓您在視圖的所有四個角上切換陰影。我還記錄了非常徹底的EdgeShadowLayer
。
我改寫@NRitH解決方案的斯威夫特3,也略有重構它:
final class SideShadowLayer: CAGradientLayer {
enum Side {
case top,
bottom,
left,
right
}
init(frame: CGRect, side: Side, shadowWidth: CGFloat,
fromColor: UIColor = .black,
toColor: UIColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0),
opacity: Float = 0.5) {
super.init()
colors = [fromColor.cgColor, toColor.cgColor]
self.opacity = opacity
switch side {
case .bottom:
startPoint = CGPoint(x: 0.5, y: 1.0)
endPoint = CGPoint(x: 0.5, y: 0.0)
self.frame = CGRect(x: 0, y: frame.height - shadowWidth, width: frame.width, height: shadowWidth)
case .top:
startPoint = CGPoint(x: 0.5, y: 0.0)
endPoint = CGPoint(x: 0.5, y: 1.0)
self.frame = CGRect(x: 0, y: 0, width: frame.width, height: shadowWidth)
case .left:
startPoint = CGPoint(x: 0.0, y: 0.5)
endPoint = CGPoint(x: 1.0, y: 0.5)
self.frame = CGRect(x: 0, y: 0, width: shadowWidth, height: frame.height)
case .right:
startPoint = CGPoint(x: 1.0, y: 0.5)
endPoint = CGPoint(x: 0.0, y: 0.5)
self.frame = CGRect(x: frame.width - shadowWidth, y: 0, width: shadowWidth, height: frame.height)
}
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
我更新@ NRitH答案,並做了擴展出來的也修改了,這樣就可以操縱多個邊緣一個去
使用
myview.addShadow(to: [.top,.bottom], radius: 15.0)
extension UIView{
func addShadow(to edges:[UIRectEdge], radius:CGFloat){
let toColor = UIColor(colorLiteralRed: 235.0/255.0, green: 235.0/255.0, blue: 235.0/255.0, alpha: 1.0)
let fromColor = UIColor(colorLiteralRed: 188.0/255.0, green: 188.0/255.0, blue: 188.0/255.0, alpha: 1.0)
// Set up its frame.
let viewFrame = self.frame
for edge in edges{
let gradientlayer = CAGradientLayer()
gradientlayer.colors = [fromColor.cgColor,toColor.cgColor]
gradientlayer.shadowRadius = radius
switch edge {
case UIRectEdge.top:
gradientlayer.startPoint = CGPoint(x: 0.5, y: 0.0)
gradientlayer.endPoint = CGPoint(x: 0.5, y: 1.0)
gradientlayer.frame = CGRect(x: 0.0, y: 0.0, width: viewFrame.width, height: gradientlayer.shadowRadius)
case UIRectEdge.bottom:
gradientlayer.startPoint = CGPoint(x: 0.5, y: 1.0)
gradientlayer.endPoint = CGPoint(x: 0.5, y: 0.0)
gradientlayer.frame = CGRect(x: 0.0, y: viewFrame.height - gradientlayer.shadowRadius, width: viewFrame.width, height: gradientlayer.shadowRadius)
case UIRectEdge.left:
gradientlayer.startPoint = CGPoint(x: 0.0, y: 0.5)
gradientlayer.endPoint = CGPoint(x: 1.0, y: 0.5)
gradientlayer.frame = CGRect(x: 0.0, y: 0.0, width: gradientlayer.shadowRadius, height: viewFrame.height)
case UIRectEdge.right:
gradientlayer.startPoint = CGPoint(x: 1.0, y: 0.5)
gradientlayer.endPoint = CGPoint(x: 0.0, y: 0.5)
gradientlayer.frame = CGRect(x: viewFrame.width - gradientlayer.shadowRadius, y: 0.0, width: gradientlayer.shadowRadius, height: viewFrame.height)
default:
break
}
self.layer.addSublayer(gradientlayer)
}
}
func removeAllSublayers(){
if let sublayers = self.layer.sublayers, !sublayers.isEmpty{
for sublayer in sublayers{
sublayer.removeFromSuperlayer()
}
}
}
}
花了我2秒鐘:https://github.com/inamiy/YIInnerShadowView – Arbitur
@gotnull我發現了這個問題,但我無法弄清楚如何只在頂部添加它。還有Arbitur,你的鏈接在我無法翻譯的objective-c中。在它的答案中,它看起來相當複雜的代碼塊和它的各個方面。它不是也使用像'CGSizeMake'這樣簡單的東西,這就是我想問這個問題的原因。我只是在尋找一種更加快速的方式 – senty
如果你想確保陰影只保留在上邊界上,不管模糊半徑/偏移量等。並且不會流入其他邊界,所以最好的辦法是在子視圖中添加一個「UIImageView」,並粘貼到頂部邊框並沿着整個寬度延伸。如果你需要在側邊進行特殊處理(就像你的截圖似乎表明的那樣),也許一個帶有插入物的可拉伸圖像將會起作用。 –