Custom UI Button not shwing title - ios

I created a custom UI Button class in swift for a follow button, however it is not showing the button title
My code
#IBDesignable
public class GradientButton: UIButton {
override public func layoutSubviews() {
super.layoutSubviews()
layoutGradientButtonLayer()
}
// MARK: Private
private func layoutGradientButtonLayer() {
let layer = UIView()
layer.frame = CGRect(x: 191, y: 257, width: 66.6, height: 24)
let gradient = CAGradientLayer()
gradient.frame = CGRect(x: 0, y: 0, width: 66.6, height: 24)
gradient.colors = [
UIColor(red: 0.09, green: 0.85, blue: 0.88, alpha: 1).cgColor,
UIColor(red: 0, green: 0.87, blue: 0.68, alpha: 1).cgColor
]
gradient.locations = [0, 1]
gradient.startPoint = CGPoint(x: 0.78, y: 1)
gradient.endPoint = CGPoint(x: 0.15, y: 1)
self.layer.cornerRadius = 10
self.layer.addSublayer(gradient)
self.clipsToBounds = true
self.setTitle("Follow", for: UIControlState.normal)
}
}
The button appears small width and doesn't have any "Follow" text in it

Change below code you will see title:
self.layer.addSublayer(gradient)
change to
self.layer.insertSublayer(gradient, at: 0)

Related

NavBar title hidden behind CAGradientLayer

I would like to add gradient layer to my navbar, but after I add it, layer hides my title, like its behind that new sublayer.
override func viewDidLoad() {
super.viewDidLoad()
self.title = "My Trips"
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
//self.navigationController?.navigationBar.layer.addSublayer(gradientLayer)
self.navigationController?.navigationBar.layer.insertSublayer(gradientLayer, at: 1)
setupGradient()
}
let gradientLayer = CAGradientLayer()
func setupGradient() {
gradientLayer.colors = [
UIColor(red: 0.259, green: 0.188, blue: 0.475, alpha: 1).cgColor,
UIColor(red: 0.11, green: 0.024, blue: 0.369, alpha: 1).cgColor
]
gradientLayer.locations = [0, 1]
gradientLayer.startPoint = CGPoint(x: 0.25, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 0.75, y: 0.5)
gradientLayer.transform = CATransform3DMakeAffineTransform(CGAffineTransform(a: 0, b: 0.58, c: -0.58, d: 0, tx: 0.5, ty: 0))
gradientLayer.bounds = (self.navigationController?.navigationBar.bounds.insetBy(dx: -0.01*view.bounds.size.width, dy: -1*view.bounds.size.height))!
}
Use this line for inserting layer.
self.navigationController?.navigationBar.subviews.first?.layer.insertSublayer(gradientLayer, at: 0)

Adding shadow layer with rounded corners on custom UIButton subclass

I'm trying to apply a shadow and rounded corners on custom UIButton subclass to use in on the storyboard
Here is my code :
import UIKit
class customButton: UIButton {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
setGradientBackground()
setShadowLayer()
}
private func setup() {
clipsToBounds = true
layer.cornerRadius = 8
}
private func setGradientBackground() {
let gradientLayer = CAGradientLayer()
gradientLayer.frame = bounds
gradientLayer.colors = [
UIColor(red: 0.18, green: 0.5, blue: 0.93, alpha: 1).cgColor,
UIColor(red: 0.18, green: 0.61, blue: 0.86, alpha: 1).cgColor
]
gradientLayer.locations = [0,1]
gradientLayer.startPoint = CGPoint(x: 0.25, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 0.75, y: 0.5)
layer.insertSublayer(gradientLayer, at: 0)
}
private func setShadowLayer(){
let subLayer = CALayer()
subLayer.frame = bounds
subLayer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: 8).cgPath
subLayer.shadowColor = UIColor.red.cgColor
subLayer.shadowOpacity = 1
subLayer.shadowRadius = 12
subLayer.shadowOffset = CGSize(width: 0, height: 2)
layer.insertSublayer(subLayer, at: 0)
}
}
When I'm setting the clipsToBounds to true it remove the shadow, so I decided to add a new sublayer func setShadowLayer() and nothing worked so far.
Try also setting the .cornerRadius on the gradient layer:
gradientLayer.endPoint = CGPoint(x: 0.75, y: 0.5)
// add this line
gradientLayer.cornerRadius = 8
layer.insertSublayer(gradientLayer, at: 0)
My result:

How to set gradient colour to UIButton in background?

Am trying to set CAGradientLayer for UIButton.
But it is not getting exactly. am I doing any wrong ?
am getting output like
You can see there is some horizontal line
Here is the code which I tried
let topColor = UIColor(red: 0.62, green: 0.38, blue: 1, alpha: 1).cgColor
let bottomColor = UIColor(red: 0.87, green: 0.51, blue: 0.93, alpha: 1).cgColor
let gradientLayer = CAGradientLayer()
gradientLayer.frame = myButton.bounds
gradientLayer.colors = [topColor, bottomColor]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
myButton.layer.insertSublayer(myButton, at: 0)
Create a Designable custom class like this
import Foundation
import UIKit
#IBDesignable class CustomButton:UIButton {
#IBInspectable var firstColor:UIColor = UIColor.clear {
didSet {
updateUI()
}
}
#IBInspectable var secondColor:UIColor = UIColor.clear {
didSet{
updateUI()
}
}
override class var layerClass: AnyClass {
get {
return CAGradientLayer.self
}
}
func updateUI(){
let gradient: CAGradientLayer = self.layer as! CAGradientLayer
gradient.frame = self.bounds
gradient.colors = [firstColor,secondColor].map { $0.cgColor }
gradient.locations = [0.0,1.0]
gradient.startPoint = CGPoint(x: 0.0, y: 1.0)
gradient.endPoint = CGPoint(x: 1.0, y: 1.0)
}
}
from your Identity inspector set your UIbutton class to CustomButtom like this
from your Attribute inspector change your gradient color to whatever you want to set
and finally your button will be like this
if you want to change the starting and endpoint to those colors
just play around with these two values
gradient.startPoint = CGPoint(x: 0.0, y: 1.0)
gradient.endPoint = CGPoint(x: 1.0, y: 1.0)
You have to update the gradient's frame when the view is laid out:
override func viewDidLayoutSubviews() {
myButton.layer.sublayers?.first?.frame = myButton.bounds
}

ScrollView with GradientColor

I am trying to make scroll view with gradient background color, but it shows me gradient color only and could not see scroll view! No error waning.
mainScrollView.frame = view.frame
imageArray = [#imageLiteral(resourceName: "business-improvement"), #imageLiteral(resourceName: "IMG_3601"), #imageLiteral(resourceName: "IMG_4261"), #imageLiteral(resourceName: "IMG_4264")]
for i in 0..<imageArray.count{
let imageView = UIImageView()
imageView.image = imageArray[i]
imageView.contentMode = .scaleAspectFit
let xPosition = self.view.frame.width * CGFloat(i)
imageView.frame = CGRect(x: xPosition, y:0, width: self.mainScrollView.frame.width, height: self.mainScrollView.frame.height)
let mainScrollView = CAGradientLayer()
self.view.backgroundColor = UIColor(red: 0.01, green:0.34, blue: 0.38, alpha: 1.0)
mainScrollView.frame = self.view.bounds
let color1 = UIColor(red: 0.11, green:0.04, blue: 0.32, alpha: 1.0).cgColor
let color2 = UIColor(red: 0.0, green:0.18, blue: 0.20, alpha: 1.0).cgColor
mainScrollView.colors = [color1, color2]
mainScrollView.frame = CGRect(x: 0, y: 0, width: 375, height: 690)
self.view.layer.addSublayer(mainScrollView)
I try the same and this works for me :
self.MyItem.applyGradient_2(colours: [UIColor(red:0.09, green:0.91, blue:0.65, alpha:1.0), UIColor(red:0.08, green:0.92, blue:0.43, alpha:1.0)])
extension UIView {
func applyGradient_2(colours: [UIColor]) -> Void {
self.applyGradient_(colours: colours, locations: nil)
}
func applyGradient_(colours: [UIColor], locations: [NSNumber]?) -> Void {
let gradient: CAGradientLayer = CAGradientLayer()
gradient.frame = self.bounds
gradient.colors = colours.map { $0.cgColor }
gradient.locations = locations
self.layer.insertSublayer(gradient, at: 0)
}
}

Gradiant in playground different from simulator

I tried to make a gradiant using playground then make it into a subclass of uiview to use it in my codebase.
The playground code is like this:
let view = UIView(frame: CGRect(x: 0, y: 0, width: 640, height: 41
))
let gradient: CAGradientLayer = CAGradientLayer(layer: view.layer)
gradient.frame = view.frame
let lightColor = UIColor(red: 157/256, green: 157/256, blue: 154/256, alpha: 1)
let darkColor = UIColor(red: 108/256, green: 104/256, blue: 104/256, alpha: 1)
gradient.colors = [lightColor.CGColor, darkColor.CGColor]
gradient.locations = [0.6 , 0.4]
gradient.startPoint = CGPoint(x: 1, y: 0.55)
gradient.endPoint = CGPoint(x: 0, y: 0.45)
view.layer.insertSublayer(gradient, atIndex: 0)
view //displayed
And display like this:
I tried to make it into my codebase with:
class GradiantView : UIView {
override var frame: CGRect {
didSet {
let gradient: CAGradientLayer = CAGradientLayer(layer: layer)
gradient.frame = bounds
let lightColor = UIColor(red: 157/256, green: 157/256, blue: 154/256, alpha: 1)
let darkColor = UIColor(red: 108/256, green: 104/256, blue: 104/256, alpha: 1)
gradient.colors = [lightColor.CGColor, darkColor.CGColor]
gradient.locations = [0.6 , 0.4]
gradient.startPoint = CGPoint(x: 1, y: 0.55)
gradient.endPoint = CGPoint(x: 0, y: 0.45)
layer.insertSublayer(gradient, atIndex: 0)
}
}
}
However, the result is like this: (no gradiant applied)
What happened and how to fix it ?
I inverted the locations and it seems to work.
I welcome any explanation on the difference between simulator and playground.
gradientLayer.locations = [0.4 , 0.6]

Resources