web-dev-qa-db-fra.com

Définir le dégradé de fond sur le bouton dans Swift

Je ne sais pas comment définir le dégradé de fond d'un bouton (sans transformer le dégradé de fond en image). C'est tellement différent d'Android.

Voici une classe où je dois définir un schéma de dégradé consigné:

import UIKit

extension CAGradientLayer {

    func backgroundGradientColor() -> CAGradientLayer {
        let topColor = UIColor(red: (0/255.0), green: (153/255.0), blue:(51/255.0), alpha: 1)
        let bottomColor = UIColor(red: (0/255.0), green: (153/255.0), blue:(255/255.0), alpha: 1)

        let gradientColors: [CGColor] = [topColor.CGColor, bottomColor.CGColor]
        let gradientLocations: [Float] = [0.0, 1.0]

        let gradientLayer: CAGradientLayer = CAGradientLayer()
        gradientLayer.colors = gradientColors
        gradientLayer.locations = gradientLocations

        return gradientLayer

    }
}

Je peux l'utiliser pour définir l'arrière-plan de l'ensemble de ma vue avec les éléments suivants:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let background = CAGradientLayer().backgroundGradientColor()
        background.frame = self.view.bounds
        self.view.layer.insertSublayer(background, atIndex: 0)
    }
    //...
}

Mais comment puis-je accéder à la vue du bouton et insérer la sous-couche ou quelque chose comme ça? J'ai googlé pendant quelques heures et je ne trouve rien qui soit utile. Je suis assez perdu avec ça.

12
Michael Yaworski

Votre code fonctionne bien. Vous devez juste vous rappeler de définir le cadre du dégradé à chaque fois. Il est préférable que la catégorie de dégradé définisse également le cadre de la vue pour vous.

De cette façon, tu n'oublies pas et ça s'applique bien.

extension UIView {
    func applyGradient(colours: [UIColor]) -> Void {
        self.applyGradient(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, atIndex: 0)
    }
}

class ViewController: UIViewController {

    @IBOutlet weak var btn: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.btn.titleLabel?.textColor = UIColor.whiteColor()

        self.btn.applyGradient([UIColor.yellowColor(), UIColor.blueColor()])
        self.view.applyGradient([UIColor.yellowColor(), UIColor.blueColor(), UIColor.redColor()], locations: [0.0, 0.5, 1.0])
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

Les boutons sont des vues. Vous lui appliquez des dégradés de la même manière que vous le feriez pour toute autre vue.

41
Brandon

Ci-dessous vous pouvez trouver la solution pour Swift3 (et Swift4 aussi) et un peu étendu (aide à l'orientation):

typealias GradientPoints = (startPoint: CGPoint, endPoint: CGPoint)

enum GradientOrientation {
    case topRightBottomLeft
    case topLeftBottomRight
    case horizontal
    case vertical

    var startPoint : CGPoint {
        return points.startPoint
    }

    var endPoint : CGPoint {
        return points.endPoint
    }

    var points : GradientPoints {
        switch self {
        case .topRightBottomLeft:
            return (CGPoint(x: 0.0,y: 1.0), CGPoint(x: 1.0,y: 0.0))
        case .topLeftBottomRight:
            return (CGPoint(x: 0.0,y: 0.0), CGPoint(x: 1,y: 1))
        case .horizontal:
            return (CGPoint(x: 0.0,y: 0.5), CGPoint(x: 1.0,y: 0.5))
        case .vertical:
            return (CGPoint(x: 0.0,y: 0.0), CGPoint(x: 0.0,y: 1.0))
        }
    }
}

extension UIView {

    func applyGradient(with colours: [UIColor], locations: [NSNumber]? = nil) {
        let gradient = CAGradientLayer()
        gradient.frame = self.bounds
        gradient.colors = colours.map { $0.cgColor }
        gradient.locations = locations
        self.layer.insertSublayer(gradient, at: 0)
    }

    func applyGradient(with colours: [UIColor], gradient orientation: GradientOrientation) {
        let gradient = CAGradientLayer()
        gradient.frame = self.bounds
        gradient.colors = colours.map { $0.cgColor }
        gradient.startPoint = orientation.startPoint
        gradient.endPoint = orientation.endPoint
        self.layer.insertSublayer(gradient, at: 0)
    }
}
13
Zeb

La réponse de @Zeb est excellente, mais il suffit de la nettoyer et de la rendre un peu plus rapide . Les propriétés en lecture seule calculées évitent d'utiliser get et return Void est redondant:

typealias GradientPoints = (startPoint: CGPoint, endPoint: CGPoint)

enum GradientOrientation {
  case topRightBottomLeft
  case topLeftBottomRight
  case horizontal
  case vertical

var startPoint: CGPoint {
    return points.startPoint
}

var endPoint: CGPoint {
    return points.endPoint
}

var points: GradientPoints {
    switch self {
    case .topRightBottomLeft:
        return (CGPoint.init(x: 0.0, y: 1.0), CGPoint.init(x: 1.0, y: 0.0))
    case .topLeftBottomRight:
        return (CGPoint.init(x: 0.0, y: 0.0), CGPoint.init(x: 1, y: 1))
    case .horizontal:
        return (CGPoint.init(x: 0.0, y: 0.5), CGPoint.init(x: 1.0, y: 0.5))
    case .vertical:
        return (CGPoint.init(x: 0.0, y: 0.0), CGPoint.init(x: 0.0, y: 1.0))
    }
  }
}

extension UIView {

func applyGradient(withColours colours: [UIColor], locations: [NSNumber]? = nil) {
    let gradient: CAGradientLayer = CAGradientLayer()
    gradient.frame = self.bounds
    gradient.colors = colours.map { $0.cgColor }
    gradient.locations = locations
    self.layer.insertSublayer(gradient, at: 0)
}

func applyGradient(withColours colours: [UIColor], gradientOrientation orientation: GradientOrientation) {
    let gradient: CAGradientLayer = CAGradientLayer()
    gradient.frame = self.bounds
    gradient.colors = colours.map { $0.cgColor }
    gradient.startPoint = orientation.startPoint
    gradient.endPoint = orientation.endPoint
    self.layer.insertSublayer(gradient, at: 0)
  }
}
5
brl214

Pour que Swift 2.0 donne des dégradés de couleur à UIButton

let gradient: CAGradientLayer = CAGradientLayer()

gradient.colors = [(UIColor(red: 59.0/255.0, green: 187.0/255.0, blue: 182.0/255.0, alpha: 1.00).CGColor), (UIColor(red: 57.0/255.0, green: 174.0/255.0, blue: 236.0/255.0, alpha: 1.00).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)
gradient.frame = CGRect(x: 0.0, y: 0.0, width: btn.frame.size.width, height: btn.frame.size.height)
btn.layer.insertSublayer(gradient, atIndex: 0)
2
Hardik Thakkar

Je les ai tous essayés c'est mon bouton init dans viewdidload

let button = UIButton()
    button.setTitle("Alper", for: .normal)
    button.layer.borderColor = UIColor.white.cgColor
    button.layer.borderWidth = 1
    view.addSubview(button)
    button.anchor(top: nil, left: nil, bottom: logo.topAnchor, right: nil, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, height: 50, width: 100)
    let gradientx = CAGradientLayer()
    gradientx.colors = [UIColor.blue,UIColor.red]
    gradientx.startPoint = CGPoint(x: 0.0, y: 0.5)
    gradientx.endPoint = CGPoint(x: 1.0, y: 1.0)
    gradientx.frame = button.bounds
    button.layer.insertSublayer(gradientx, at: 0)

anchor est une extension, il s’agit donc d’un gradient non pertinent.

1
Alper

Il y a déjà beaucoup de réponses là-bas que je veux ajouter ce que j'ai fait pour y parvenir. J'utilise ce bouton de dégradé personnalisé

import Foundation
import UIKit

class GradientButton: UIButton {

    let gradientColors : [UIColor]
    let startPoint : CGPoint
    let endPoint : CGPoint

    required init(gradientColors: [UIColor] = [UIColor.red, UIColor.blue],
                  startPoint: CGPoint = CGPoint(x: 0, y: 0.5),
                  endPoint: CGPoint = CGPoint(x: 1, y: 0.5)) {
        self.gradientColors = gradientColors
        self.startPoint = startPoint
        self.endPoint = endPoint

        super.init(frame: .zero)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        let halfOfButtonHeight = layer.frame.height / 2
        contentEdgeInsets = UIEdgeInsets(top: 10, left: halfOfButtonHeight, bottom: 10, right: halfOfButtonHeight)

        layer.anchorPoint = CGPoint(x: 0.5, y: 0.5)

        backgroundColor = UIColor.clear

        // setup gradient

        let gradient = CAGradientLayer()
        gradient.frame = bounds
        gradient.colors = gradientColors.map { $0.cgColor }
        gradient.startPoint = startPoint
        gradient.endPoint = endPoint
        gradient.cornerRadius = 4

        // replace gradient as needed
        if let oldGradient = layer.sublayers?[0] as? CAGradientLayer {
            layer.replaceSublayer(oldGradient, with: gradient)
        } else {
            layer.insertSublayer(gradient, below: nil)
        }

        // setup shadow

        layer.shadowColor = UIColor.darkGray.cgColor
        layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: halfOfButtonHeight).cgPath
        layer.shadowOffset = CGSize(width: 0.0, height: 1.0)
        layer.shadowOpacity = 0.85
        layer.shadowRadius = 4.0
    }

    override var isHighlighted: Bool {
        didSet {
            let newOpacity : Float = isHighlighted ? 0.6 : 0.85
            let newRadius : CGFloat = isHighlighted ? 6.0 : 4.0

            let shadowOpacityAnimation = CABasicAnimation()
            shadowOpacityAnimation.keyPath = "shadowOpacity"
            shadowOpacityAnimation.fromValue = layer.shadowOpacity
            shadowOpacityAnimation.toValue = newOpacity
            shadowOpacityAnimation.duration = 0.1

            let shadowRadiusAnimation = CABasicAnimation()
            shadowRadiusAnimation.keyPath = "shadowRadius"
            shadowRadiusAnimation.fromValue = layer.shadowRadius
            shadowRadiusAnimation.toValue = newRadius
            shadowRadiusAnimation.duration = 0.1

            layer.add(shadowOpacityAnimation, forKey: "shadowOpacity")
            layer.add(shadowRadiusAnimation, forKey: "shadowRadius")

            layer.shadowOpacity = newOpacity
            layer.shadowRadius = newRadius

            let xScale : CGFloat = isHighlighted ? 1.025 : 1.0
            let yScale : CGFloat = isHighlighted ? 1.05 : 1.0
            UIView.animate(withDuration: 0.1) {
                let transformation = CGAffineTransform(scaleX: xScale, y: yScale)
                self.transform = transformation
            }
        }
    }
}

Vous pouvez créer une instance de Gradient Button comme ceci.

let button = GradientButton.init(gradientColors:[UIColor.black, UIColor.white], startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 0, y: 1))
0
Ngima Sherpa

 enter image description here

   class ButtonGradient : UIButton {
        override func layoutSubviews() {

            let layer : CAGradientLayer = CAGradientLayer()
            layer.frame.size = self.frame.size
            layer.frame.Origin = CGPoint(x: 0, y: 0)

            //   layer.cornerRadius = CGFloat(frame.width / 20)
            let color0 = UIColor(red:255/255, green:122/255, blue:0/255, alpha:1.0).cgColor
            let color1 = UIColor(red:255/255, green:176/255, blue: 0/255, alpha:1.0).cgColor
            let color2 = UIColor(red:250/255, green:98/255, blue: 44/255, alpha:1.0).cgColor
            layer.locations = [0.5, 1.0]
            layer.startPoint = CGPoint(x: 0.0, y: 0.5)
            layer.endPoint = CGPoint(x: 0.5, y: 0.5)
            layer.colors = [color2,color0,color1]

            self.layer.insertSublayer(layer, at: 0)
        }
    }

Après cela, assignez directement la classe "ButtonGredient" à un bouton particulier dans Storyboard.

0
Deviyani Swami

Essayez ça marche pour moi,

     let button = UIButton(frame: CGRect(x: 60, y: 150, width: 200, height: 60))
    button.setTitle("Email", for: .normal)
    button.backgroundColor = .red
    button.setTitleColor(UIColor.black, for: .normal)
    button.addTarget(self, action: #selector(self.buttonTapped), for: .touchUpInside)

    // Apply Gradient Color
    let gradientLayer:CAGradientLayer = CAGradientLayer()
    gradientLayer.frame.size = button.frame.size
    gradientLayer.colors =
        [UIColor.white.cgColor,UIColor.green.withAlphaComponent(1).cgColor]
    //Use diffrent colors
    button.layer.addSublayer(gradientLayer)
    self.view.addSubview(button)

 enter image description here

Vous pouvez ajouter des points de départ et d'arrivée de la couleur du dégradé.

 gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
 gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)

 enter image description here

Pour plus de détails, voir la référence CAGradientLayer doc

0
Jaywant Khedkar