Shadow at top side of UIView only - swift

How can I remove shadow from bottom side of my view?
This is code for my shadowView:
class ShadowViewWhite: UIView {
init() {
super.init(frame: .zero)
backgroundColor = .white
layer.shadowColor = UIColor(red: 0.5, green: 0.5, blue: 0.65, alpha: 0.9).cgColor
layer.shadowOpacity = 1
layer.shadowRadius = 40
layer.shadowOffset = CGSize(width: 0, height: -12)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
That's how it looks so far. I need shadow to be only at the top side of my view.

A combination of reducing the shadowRadius and shadowOffset should help you. I have attached my code below which should help you.
class ShadowViewWhite: UIView {
override init(frame:CGRect) {
super.init(frame: frame)
backgroundColor = .white
layer.shadowColor = UIColor(red: 0.5, green: 0.5, blue: 0.65, alpha: 0.9).cgColor
layer.shadowOpacity = 1
layer.shadowRadius = 20
layer.shadowOffset = CGSize(width: 0, height: -40)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
This code will produce the following image:

Change shadowRadius property. Ex:
layer.shadowRadius = 24

Using lower values of shadow radius can help. You can try using shadowRadius = 20.

Related

custom UIButton class - gradient going out off button borders

I'm doing custom UIButton class and I want it to have gradient background. My gradient color is looking perfect but it goes out of button borders
My code:
class CustomButton: UIButton{
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
func setup(){
layer.cornerRadius = 25.0
layer.borderWidth = 1
gradientLayer.frame = layer.bounds
addShadow()
}
private lazy var gradientLayer: CAGradientLayer = {
let color1 = UIColor(red: 254.0/255.0, green: 79.0/255.0, blue: 50.0/255.0, alpha: 1.0).cgColor
let color2 = UIColor(red: 255.0/255.0, green: 26.0/255.0, blue: 107.0/255.0, alpha: 1.0).cgColor
let gradient = CAGradientLayer()
gradient.frame = layer.bounds
gradient.colors = [color1, color2]
gradient.startPoint = CGPoint(x: 0, y: 0.5)
gradient.endPoint = CGPoint(x: 1, y: 0.5)
gradient.locations = [0,1]
gradient.cornerRadius = 25
layer.insertSublayer(gradient, at: 0)
return gradient
}()
func addShadow(){
layer.shadowOpacity = 1
layer.shadowRadius = 1.0
layer.shadowColor = UIColor.black.cgColor
layer.shadowOpacity = 1
layer.shadowOffset = CGSize(width: 0, height: 3)
}
}
And here's how it looks:
Remove gradientLayer.frame from setup and add in layoutSubviews.
Also set self.bounds instead of layer.bounds.
override func layoutSubviews() {
super.layoutSubviews()
gradientLayer.frame = self.bounds // < Here
}
Note : Remove gradient.frame = layer.bounds from var gradientLayer. Not needed.
Just override layerClass to avoid resizing issue (Auto resize with constrains)
class CustomButton: UIButton{
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
override class var layerClass: AnyClass {
CAGradientLayer.self
}
var gradientLayer: CAGradientLayer {
layer as! CAGradientLayer
}
func setup(){
gradientLayer.cornerRadius = 25.0
gradientLayer.borderWidth = 1
let color1 = UIColor(red: 254.0/255.0, green: 79.0/255.0, blue: 50.0/255.0, alpha: 1.0).cgColor
let color2 = UIColor(red: 255.0/255.0, green: 26.0/255.0, blue: 107.0/255.0, alpha: 1.0).cgColor
gradientLayer.colors = [color1, color2]
gradientLayer.startPoint = CGPoint(x: 0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1, y: 0.5)
gradientLayer.locations = [0,1]
gradientLayer.shadowOpacity = 1
gradientLayer.shadowRadius = 1.0
gradientLayer.shadowColor = UIColor.black.cgColor
gradientLayer.shadowOpacity = 1
gradientLayer.shadowOffset = CGSize(width: 0, height: 3)
}
}

Swift shadow does not spread correctly

I'm been trying to create a shadow for my UIView. I looked around and found an extension for the CALayer class from this post. https://stackoverflow.com/a/48489506/9188318
So far its been working well for me until I try to put in a non 0 number for the spread.
With the spread being 0. This is the result
And here is the result using a spread of 1
And it gets even worse with a spread of 5
The problem that I'm having is that it doesn't have rounded corners and I have no idea how to fix this. Heres my code for the UIView that uses this view. The extension that is used to make the shadow is in the post above.
UIView code
class FileCalculateOperatorSelectionButton : UIView {
private var isActivated : Bool = false
//Background colors
private var unSelectedBackgroundColor : UIColor = UIColor(red: 178/255, green: 90/255, blue: 253/255, alpha: 1.0)
private var selectedBackgroundColor : UIColor = UIColor.white
override init(frame: CGRect) {
super.init(frame: frame)
self.commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
self.commonInit()
}
private func commonInit() {
self.layer.cornerRadius = self.frame.height/2
self.backgroundColor = self.unSelectedBackgroundColor
let shadowColor = UIColor(red: 0xC8, green: 0xC6, blue: 0xC6)
//Change the spread argument here
self.layer.applySketchShadow(color: .black, alpha: 0.5, x: 0, y: 0, blur: 5, spread: 0)
}
}
Try setting the layer's masksToBounds property to true.
self.layer.masksToBounds = true
Change shadowPath in applySketchShadow function in CALayer extension like below;
// shadowPath = UIBezierPath(rect: rect).cgPath
shadowPath = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).cgPath
when spread: 1

Custom UILabel class does not change properties?

I have a custom UILabel class. I create one CustomLabel and positioned it but it doesn't have properties that I gave in the custom UILabel class.
class CustomLabel: UILabel {
override func awakeFromNib() {
backgroundColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
textColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
textAlignment = .center
}
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
and here is my ViewController
class Controller: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let lblPos = CGRect(x: view.frame.size.width / 2 - 75 , y: 100, width: 150 , height: 30)
let samsungLbl = CustomLabel(frame: lblPos)
samsungLbl.text = "Samsung"
view.addSubview(samsungLbl)
}
}
The problem is that you set properties at awakeFromNib method. From Apple Documentation
awakeFromNib()
The nib-loading infrastructure sends an awakeFromNib message to each object recreated from a nib archive
So this method is called when your object is loaded from a .xib file or a storyboad. Since you creating your object programmatically by calling init(frame: CGRect), your awaktFromNib is never called.
You need to move your setup code into another method and call from the initializer.
func setupStyle() {
backgroundColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
textColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
textAlignment = .center
}
override init(frame: CGRect) {
super.init(frame: frame)
self.setupStyle()
}

Creating custom Color for UIColor

I have a question about creating a custom UIColor in swift.
I used the following extension code:
import UIKit
extension UIColor {
convenience init(red: Int, green: Int, blue: Int) {
let newRed = CGFloat(red)/255
let newGreen = CGFloat(green)/255
let newBlue = CGFloat(blue)/255
self.init(red: newRed, green: newGreen, blue: newBlue, alpha: 1.0)
}
}
let brandBlue = UIColor(red: 0, green: 127, blue: 255)
I want to load it in, shadowColor, under the following code:
class squareButton : UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
self.layer.cornerRadius = 10.0
self.layer.shadowColor = (Loading code here)
self.layer.shadowRadius = 1.5
self.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
self.layer.shadowOpacity = 0.6
self.layer.masksToBounds = false
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.layer.cornerRadius = 10.0
self.layer.shadowColor = (Loading code here)
self.layer.shadowRadius = 1.5
self.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
self.layer.shadowOpacity = 0.6
self.layer.masksToBounds = false
}
}
But every combination I used won't work. Every time it says that I should use as! CGColor but when I do that, the app crashes.
Please help me
Thank you
In your code you are currently providing to self.layer.shadowColor = (Loading code here) a UIColor this should cause a compiler error.
The extension you created is fine. Just use the .cgColor property of UIColor after you instantiated your new UIColor instance. This would then be the example code:
class SquareButton: UIButton {
let brandBlue: UIColor = UIColor(red: 0, green: 127, blue: 255)
override init(frame: CGRect) {
super.init(frame: frame)
self.layer.cornerRadius = 10.0
self.layer.shadowColor = brandBlue.cgColor
self.layer.shadowRadius = 1.5
self.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
self.layer.shadowOpacity = 0.6
self.layer.masksToBounds = false
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.layer.cornerRadius = 10.0
self.layer.shadowColor = brandBlue.cgColor
self.layer.shadowRadius = 1.5
self.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
self.layer.shadowOpacity = 0.6
self.layer.masksToBounds = false
}
}
CGColor and UIColorare not the same and CALayer.shadowColor needs to be a CGColor. You can get a CGColor from a UIColor by calling the cgColor property on a UIColor instance.
Like this: self.layer.shadowColor = UIColor(red: 0, green: 127, blue: 255).cgColor

my drawRect function will not update

I want the values for the colors of the circle to update when the variables(redd1,greenn1,bluee1) are changed by the steppers in my ViewController. The original circle is drawn by drawRect.
var redd1 = 0.0;
var greenn1 = 0.0;
var bluee1 = 0.0;
override init(frame: CGRect)
{
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
}
override func drawRect(rect: CGRect)
{
let circle2 = UIView(frame: CGRect(x: -25.0, y: 10.0, width: 100.0, height:100.0))
circle2.layer.cornerRadius = 50.0
let startingColor2 = UIColor(red: (CGFloat(redd1))/255, green: (CGFloat (greenn1))/255, blue: (CGFloat(bluee1))/255, alpha: 1.0)
circle2.backgroundColor = startingColor2;
addSubview(circle2);
}
I tried creating a new function that draws a new circle on top of the old one. It is called by the stepper. The new function, updateColor(), receives the new value from the stepper. This partially works because it prints out the correct new values, but never draws the new circle.
func updateColor()
{
let circle = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0))
circle.layer.cornerRadius = 50.0;
let startingColor = UIColor(red: (CGFloat(redd1))/255, green: (CGFloat(greenn1))/255, blue: (CGFloat(bluee1))/255, alpha: 1.0)
circle.backgroundColor = startingColor;
addSubview(circle);
}
I'm not so good in Swift, but that's a simple way how i wood do it:
var circle2: UIView
override func drawRect(rect: CGRect) {
circle2 = UIView(frame: CGRect(x: -25.0, y: 10.0, width: 100.0, height:100.0))
circle2.layer.cornerRadius = 50.0
let startingColor2 = UIColor(red: (CGFloat(redd1))/255, green: (CGFloat (greenn1))/255, blue: (CGFloat(bluee1))/255, alpha: 1.0)
circle2.backgroundColor = startingColor2;
addSubview(circle2);
}
#IBAction valueChanged(sender: UIStepper) {
changeColor(color(the Color you want), Int(the Int value you want the color to change at))
}
func changeColor(color: UIColor, number: Int) {
if stepper.value == number {
circle2.backgroundColor = color
}
}
You have to create a IBAction for the stepper of the type value changed and call the method for every color and to it belonging Int in the IBAction for the stepper. So every time + or - on the stepper is pressed the IBAction calls the changeColor method and the changeColor method tests which color should be set to circle2.