Граница градиента UIButton с радиусом угла - PullRequest
0 голосов
/ 27 сентября 2018

Я написал код, который работает на iPhone X, но не работает на iPhone SE. Вот что мы имеем на iPhone SE

У кого-нибудь есть идеи, почему он правильно работает на iPhone X и не работает на iPhone SE

Я вызываю эту функцию в 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)
    }
}

1 Ответ

0 голосов
/ 27 сентября 2018

Так как viewDidLayoutSubviews вызывается несколько раз, вы должны убедиться, что вы создали градиентный слой только один раз.Добавьте проверку следующим образом:

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