Как применить цвет границы градиента к UIButton?

Я хочу добиться чего-то подобного. Я искал это. Я получаю предложения, что я могу разместить вид градиента за кнопкой с высотой и шириной больше, чем кнопка. Но мне нужен точный радиус угла и цвет границы с градиентами.

пример изображения


person Aalok verma    schedule 02.11.2019    source источник
comment
Вы смотрели на этот ответ? stackoverflow.com/a/36836787   -  person Hima    schedule 02.11.2019


Ответы (1)


Вы можете создать свой собственный подкласс BorderedButton, который будет:

  • Добавьте подслой градиента;
  • Создайте слой формы, состоящий из контура границы; А также
  • Используйте этот слой формы в качестве маски для слоя градиента, чтобы получить границу градиента в форме пути.

E.g.:

@IBDesignable
class BorderedButton: UIButton {
    @IBInspectable var lineWidth:    CGFloat = 3  { didSet { setNeedsLayout() } }
    @IBInspectable var cornerRadius: CGFloat = 10 { didSet { setNeedsLayout() } }

    let borderLayer: CAGradientLayer = {
        let borderLayer = CAGradientLayer()
        borderLayer.type = .axial
        borderLayer.colors = [#colorLiteral(red: 0.6135130525, green: 0.3031745553, blue: 0.9506058097, alpha: 1).cgColor, #colorLiteral(red: 0.9306473136, green: 0.1160953864, blue: 0.8244602084, alpha: 1).cgColor]
        borderLayer.startPoint = CGPoint(x: 0, y: 1)
        borderLayer.endPoint = CGPoint(x: 1, y: 0)
        return borderLayer
    }()

    override init(frame: CGRect = .zero) {
        super.init(frame: frame)
        configure()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        configure()
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        borderLayer.frame = bounds

        let mask = CAShapeLayer()
        let rect = bounds.insetBy(dx: lineWidth / 2, dy: lineWidth / 2)
        mask.path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).cgPath
        mask.lineWidth = lineWidth
        mask.fillColor = UIColor.clear.cgColor
        mask.strokeColor = UIColor.white.cgColor
        borderLayer.mask = mask
    }
}

private extension BorderedButton {
    func configure() {
        layer.addSublayer(borderLayer)
    }
}

Обратите внимание, что:

  • Я обновляю frame слоя градиента и путь, который используется как mask внутри метода layoutSubviews, что гарантирует правильную визуализацию границы при изменении размера (например, вы используете ограничения для определения размера представления).
  • Я сделал это @IBDesignable так, что вы даже можете добавить его в раскадровку, и вы увидите, что оно отображается правильно.
  • Я сделал cornerRadius и lineWidth равными @IBInspectable, чтобы вы могли настроить их в IB (и, поскольку у них есть didSet наблюдатели, которые устанавливают «макет потребностей», они гарантируют, что изменения будут видны в раскадровке).

Во всяком случае, это дает:

введите здесь описание изображения

person Rob    schedule 02.11.2019