Ich habe UI-Elemente in der Skizze entworfen, und eines davon hat einen Schatten mit Unschärfe 1 und Ausbreitung 0. Ich habe das Dokument für die Layer-Eigenschaft Layer angesehen, und die Ebene hat nichts namens Spread oder Unschärfe oder etwas Äquivalent (das einzige Steuerelement war nur shadowOpacity) Wie kann man Dinge wie Unschärfe und Ausbreitung kontrollieren?
BEARBEITEN:
Hier sind meine Einstellungen in Sketch:
Und ich möchte, dass mein Schatten so aussieht:
Und so sieht es im Moment aus:
Beachten Sie, dass Sie auf das Bild klicken müssen, um den Schatten zu sehen.
Mein Code lautet wie folgt:
func setupLayer(){
view.layer.cornerRadius = 2
view.layer.shadowColor = Colors.Shadow.CGColor
view.layer.shadowOffset = CGSize(width: 0, height: 1)
view.layer.shadowOpacity = 0.9
view.layer.shadowRadius = 5
}
So können Sie alle 6 Sketch-Schatteneigenschaften nahezu perfekt auf die Ebene eines UIView anwenden:
extension CALayer {
func applySketchShadow(
color: UIColor = .black,
alpha: Float = 0.5,
x: CGFloat = 0,
y: CGFloat = 2,
blur: CGFloat = 4,
spread: CGFloat = 0)
{
shadowColor = color.cgColor
shadowOpacity = alpha
shadowOffset = CGSize(width: x, height: y)
shadowRadius = blur / 2.0
if spread == 0 {
shadowPath = nil
} else {
let dx = -spread
let rect = bounds.insetBy(dx: dx, dy: dx)
shadowPath = UIBezierPath(rect: rect).cgPath
}
}
}
Angenommen, wir möchten Folgendes darstellen:
Das geht ganz einfach über:
myView.layer.applySketchShadow(
color: .black,
alpha: 0.5,
x: 0,
y: 0,
blur: 4,
spread: 0)
oder prägnanter:
myView.layer.applySketchShadow(y: 0)
Beispiel:
Left: iPhone 8 UIView-Screenshot; rechts: Rechteck skizzieren.
Hinweis:
spread
, die nicht Null ist, wird ein Pfad auf der Grundlage der bounds
des CALayer hart kodiert. Wenn sich die Grenzen der Ebene ändern, sollten Sie die applySketchShadow()
-Methode erneut aufrufen.Sie können dies versuchen .... Sie können mit den Werten spielen .. _ Die shadowRadius
bestimmt die Menge der Unschärfe. shadowOffset
gibt an, wohin der Schatten geht.
Swift 2.0
let radius: CGFloat = demoView.frame.width / 2.0 //change it to .height if you need spread for height
let shadowPath = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 2.1 * radius, height: demoView.frame.height))
//Change 2.1 to amount of spread you need and for height replace the code for height
demoView.layer.cornerRadius = 2
demoView.layer.shadowColor = UIColor.blackColor().CGColor
demoView.layer.shadowOffset = CGSize(width: 0.5, height: 0.4) //Here you control x and y
demoView.layer.shadowOpacity = 0.5
demoView.layer.shadowRadius = 5.0 //Here your control your blur
demoView.layer.masksToBounds = false
demoView.layer.shadowPath = shadowPath.CGPath
Swift 3.0
let radius: CGFloat = demoView.frame.width / 2.0 //change it to .height if you need spread for height
let shadowPath = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 2.1 * radius, height: demoView.frame.height))
//Change 2.1 to amount of spread you need and for height replace the code for height
demoView.layer.cornerRadius = 2
demoView.layer.shadowColor = UIColor.black.cgColor
demoView.layer.shadowOffset = CGSize(width: 0.5, height: 0.4) //Here you control x and y
demoView.layer.shadowOpacity = 0.5
demoView.layer.shadowRadius = 5.0 //Here your control your blur
demoView.layer.masksToBounds = false
demoView.layer.shadowPath = shadowPath.cgPath
Beispiel mit Aufstrich
Einen grundlegenden Schatten erzeugen
demoView.layer.cornerRadius = 2
demoView.layer.shadowColor = UIColor.blackColor().CGColor
demoView.layer.shadowOffset = CGSizeMake(0.5, 4.0); //Here your control your spread
demoView.layer.shadowOpacity = 0.5
demoView.layer.shadowRadius = 5.0 //Here your control your blur
Grundlegendes Schattenbeispiel in Swift 2.0
Dieser Code hat für mich sehr gut funktioniert:
yourView.layer.shadowOpacity = 0.2 // opacity, 20%
yourView.layer.shadowColor = UIColor.black.cgColor
yourView.layer.shadowRadius = 2 // HALF of blur
yourView.layer.shadowOffset = CGSize(width: 0, height: 2) // Spread x, y
yourView.layer.masksToBounds = false
Sketch Shadow mit IBDesignable und IBInspectable in Swift 4
SKETCH- UND XCODE-SEITE VON SEITE
CODE
@IBDesignable class ShadowView: UIView {
@IBInspectable var shadowColor: UIColor? {
get {
if let color = layer.shadowColor {
return UIColor(cgColor: color)
}
return nil
}
set {
if let color = newValue {
layer.shadowColor = color.cgColor
} else {
layer.shadowColor = nil
}
}
}
@IBInspectable var shadowOpacity: Float {
get {
return layer.shadowOpacity
}
set {
layer.shadowOpacity = newValue
}
}
@IBInspectable var shadowOffset: CGPoint {
get {
return CGPoint(x: layer.shadowOffset.width, y:layer.shadowOffset.height)
}
set {
layer.shadowOffset = CGSize(width: newValue.x, height: newValue.y)
}
}
@IBInspectable var shadowBlur: CGFloat {
get {
return layer.shadowRadius
}
set {
layer.shadowRadius = newValue / 2.0
}
}
@IBInspectable var shadowSpread: CGFloat = 0 {
didSet {
if shadowSpread == 0 {
layer.shadowPath = nil
} else {
let dx = -shadowSpread
let rect = bounds.insetBy(dx: dx, dy: dx)
layer.shadowPath = UIBezierPath(rect: rect).cgPath
}
}
}
}
AUSGABE
WIE VERWENDEN SIE ES
Meine Lösung basierend auf diesem Beitrag antwortet: (Swift 3)
let shadowPath = UIBezierPath(rect: CGRect(x: -1,
y: -2,
width: target.frame.width + 2,
height: target.frame.height + 2))
target.layer.shadowColor = UIColor(hexString: shadowColor).cgColor
target.layer.shadowOffset = CGSize(width: CGFloat(shadowOffsetX), height: CGFloat(shadowOffsetY))
target.layer.masksToBounds = false
target.layer.shadowOpacity = Float(shadowOpacity)
target.layer.shadowPath = shadowPath.cgPath
Für diejenigen, die versuchen, einen Schatten auf einen vordefinierten Pfad anzuwenden (z. B. für eine kreisförmige Ansicht), habe ich Folgendes erreicht:
extension CALayer {
func applyShadow(color: UIColor = .black,
alpha: Float = 0.5,
x: CGFloat = 0,
y: CGFloat = 2,
blur: CGFloat = 4,
spread: CGFloat = 0,
path: UIBezierPath? = nil) {
shadowColor = color.cgColor
shadowOpacity = alpha
shadowRadius = blur / 2
if let path = path {
if spread == 0 {
shadowOffset = CGSize(width: x, height: y)
} else {
let scaleX = (path.bounds.width + (spread * 2)) / path.bounds.width
let scaleY = (path.bounds.height + (spread * 2)) / path.bounds.height
path.apply(CGAffineTransform(translationX: x + -spread, y: y + -spread).scaledBy(x: scaleX, y: scaleY))
shadowPath = path.cgPath
}
} else {
shadowOffset = CGSize(width: x, height: y)
if spread == 0 {
shadowPath = nil
} else {
let dx = -spread
let rect = bounds.insetBy(dx: dx, dy: dx)
shadowPath = UIBezierPath(rect: rect).cgPath
}
}
shouldRasterize = true
rasterizationScale = UIScreen.main.scale
}
}
Ich werde später einige Beispiele posten, aber das hat sich für kreisrunde Ansichten für mich erledigt.
Es mag ein wenig Diggin in der Geschichte sein, aber vielleicht hatten einige das gleiche Problem. Ich habe Codebeispiel von akzeptierter Antwort verwendet. Die Auswirkungen sind jedoch recht unterschiedlich: - Der y-Wert muss etwa halb so groß sein wie derselbe Wert in der Skizze - Ich habe versucht, einen Schatten auf die Navigationsleiste anzuwenden, und der Effekt ist sehr unterschiedlich - kaum sichtbar, wenn ich dieselben Werte wie in der Skizze verwendet.
Es scheint also, dass die Methode die Skizzenparameter überhaupt nicht widerspiegelt.