简体   繁体   English

带有角半径的渐变UIButton边框

[英]Gradient UIButton's border with corner radius

I wrote the code, which works on iPhone X, but doesn't work on iPhone SE. 我编写了该代码,该代码可在iPhone X上使用,但不适用于iPhone SE。 Here's what we have on iPhone SE 这就是我们在iPhone SE上拥有的

Have someone any ideas why it works on iPhone X correctly and doesn't on iPhone SE 有任何人知道为什么它可以在iPhone X上正确运行而不能在iPhone SE上运行

I call this function in viewDidLayoutSubviews() 我在viewDidLayoutSubviews()中调用此函数

extension UIView {
    enum Direction {
        case horizontal
        case vertical
    }

    func addGradient(cornerRadius: CGFloat, colors: [UIColor], lineWidth: CGFloat, direction: Direction) {
       self.layer.cornerRadius = cornerRadius
        let gradient = CAGradientLayer()
        gradient.frame = bounds
        gradient.colors = colors.map({ (color) -> CGColor in
            color.cgColor
        })

        switch direction {
        case .horizontal:
            gradient.startPoint = CGPoint(x: 0, y: 1)
            gradient.endPoint = CGPoint(x: 1, y: 1)
        case .vertical:
            gradient.startPoint = CGPoint(x: 0, y: 0)
            gradient.endPoint = CGPoint(x: 0, y: 1)
        }

        var shadowLayer: CAShapeLayer!
        shadowLayer = CAShapeLayer()
        shadowLayer.lineWidth = lineWidth
        shadowLayer.path = UIBezierPath(roundedRect: self.bounds.insetBy(dx: lineWidth, dy: lineWidth), cornerRadius: cornerRadius).cgPath
        shadowLayer.fillColor = nil
        shadowLayer.strokeColor = UIColor.black.cgColor
        gradient.mask = shadowLayer
        self.layer.addSublayer(gradient)
    }
}

Since viewDidLayoutSubviews gets called multiple times you have to make sure that you create the gradient layer only once. 由于多次调用viewDidLayoutSubviews ,因此必须确保仅创建一次渐变图层。 Add a check like this: 添加这样的支票:

func addGradient(cornerRadius: CGFloat, colors: [UIColor], lineWidth: CGFloat, direction: Direction) {
    self.layer.cornerRadius = cornerRadius

    if let gradient = self.layer.sublayers?.last as? CAGradientLayer {
        // gradient layer already exists - update its frame
        gradient.frame = bounds
    } else {
        // gradient layer does not exist yet - create it
        let gradient = CAGradientLayer()
        gradient.frame = bounds
        gradient.colors = colors.map({ (color) -> CGColor in
            color.cgColor
        })

        switch direction {
        case .horizontal:
            gradient.startPoint = CGPoint(x: 0, y: 1)
            gradient.endPoint = CGPoint(x: 1, y: 1)
        case .vertical:
            gradient.startPoint = CGPoint(x: 0, y: 0)
            gradient.endPoint = CGPoint(x: 0, y: 1)
        }

        var shadowLayer: CAShapeLayer!
        shadowLayer = CAShapeLayer()
        let rectPath = UIBezierPath(roundedRect: self.bounds.insetBy(dx: lineWidth, dy: lineWidth), cornerRadius: cornerRadius).cgPath
        shadowLayer.path = rectPath
        shadowLayer.lineWidth = lineWidth
        shadowLayer.fillColor = nil
        shadowLayer.strokeColor = UIColor.black.cgColor
        gradient.mask = shadowLayer
        self.layer.addSublayer(gradient)
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM