Set Background Gradient on Button in Swift

前端 未结 10 1160
礼貌的吻别
礼貌的吻别 2020-12-12 21:54

I have no idea how to set the background gradient on a button (without making the background gradient an image). This is so different from Android.

Here\'s a class I

相关标签:
10条回答
  • 2020-12-12 22:03

    @Zeb answer is great but just to clean it up and make it a little more swifty. Computed read-only properties should avoid using get and returning Void is redundant:

    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(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)
      }
    }
    
    0 讨论(0)
  • 2020-12-12 22:08

    Here below you can find the solution for Swift3 (and Swift4 too) and a little bit extended (orientation helper):

    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)
        }
    }
    
    0 讨论(0)
  • 2020-12-12 22:15

    Here, I have taken one UIView and add button in it.

         @IBOutlet weak var btnCenter: UIButton!
         @IBOutlet weak var viewCenter: UIView!
    
        // Create a gradient layer
        let gradient = CAGradientLayer()
    
        // gradient colors in order which they will visually appear
        gradient.colors = [UIColor.yello.cgColor, UIColor.blue.cgColor]
    
        // Gradient from left to right
        gradient.startPoint = CGPoint(x: 0.0, y: 0.5)
        gradient.endPoint = CGPoint(x: 1.0, y: 0.5)
    
        // set the gradient layer to the same size as the view
        gradient.frame = viewCenter.bounds
    
        // add the gradient layer to the views layer for rendering
        viewCenter.layer.insertSublayer(gradient, at: 0)
    
        // Tha magic! Set the button as the views mask
        viewCenter.mask = btnCenter
    
        //Set corner Radius and border Width of button
        btnCenter.layer.cornerRadius =  btnCenter.frame.size.height / 2
        btnCenter.layer.borderWidth = 5.0
    

    0 讨论(0)
  • 2020-12-12 22:16

    For Swift 2.0 to give gradients color to 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)
    
    0 讨论(0)
  • 2020-12-12 22:17

    There are already many answers there I want add what I did to achieve this. I use this custom Button GradientButton

    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
                }
            }
        }
    }
    

    You can make GradientButton instance like this.

    let button = GradientButton.init(gradientColors:[UIColor.black, UIColor.white], startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 0, y: 1))
    
    0 讨论(0)
  • 2020-12-12 22:20

       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)
            }
        }
    

    After that directly assign "ButtonGredient" class to particular button in Storyboard.

    0 讨论(0)
提交回复
热议问题