Как нарисовать кнопку с градиентной рамкой?

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

Кнопка с градиентной рамкой. Никогда не пробуйте это раньше. До сих пор я только что создавал градиентные фоновые представления 2 раза в предыдущих проектах. Погуглил и нашел хорошие результаты.

let button = UIButton(frame: CGRect(x: 100, y: 100, width: 200, height: 100))
let gradient = CAGradientLayer()
gradient.frame =  CGRect(origin: .zero, size: button.frame.size)
gradient.colors = [UIColor.blue.cgColor, UIColor.green.cgColor]
let shape = CAShapeLayer()
shape.lineWidth = 2
shape.path = UIBezierPath(rect: button.bounds).cgPath
shape.strokeColor = UIColor.black.cgColor
shape.fillColor = UIColor.clear.cgColor
gradient.mask = shape
button.layer.addSublayer(gradient)

Идеально.

Прямоугольники со скругленными углами повсюду! (Стив Джобс)

Попытался сделать кнопку с закругленным углом. А также…

Упс. Это не работает как то, что мне нужно. Провел еще несколько исследований и нашел еще один отличный от Ян Хиршфельд

Это работает как шарм, но это не мое любимое решение. Мне нужен проект Swifty, а не комбинация с Objective-C. Так не пытаюсь ли я сделать что-то проще и легче для себя?

Идея

  • Создайте кнопку с градиентным фоном
  • Заполните его сплошным цветом
  • Установить отступ для границ кнопки — это ширина границы

Разговор дешевый. Покажи мне код. (Лайнус Торвальдс)

Настройка градиента

func setupView() {    
    let gradientLayer = CAGradientLayer()
    gradientLayer.frame = bounds
    gradientLayer.colors = colors.map({ return $0.cgColor })
    gradientLayer.startPoint = startPoint
    gradientLayer.endPoint = endPoint
    layer.insertSublayer(gradientLayer, at: 0) // * important

    let backgroundView = UIView()
    backgroundView.translatesAutoresizingMaskIntoConstraints = false
    insertSubview(backgroundView, at: 1) // (1)
    backgroundView.backgroundColor = backgroundColor // (2)
    backgroundView.fill(toView: self, space: UIEdgeInsets(space: borderWidth)) // (3)
    createRoundCorner(cornerRadius)
}

(1)

  • Самое главное здесь — порядок слоя градиента и вида фона.
  • Метка заголовка будет перекрываться, и когда мы используем addSublayer или же addSubview.

(2)

  • backgroundColor: свойство вида из UIKit.

(3)

  • borderWidth — это новое свойство, мы будем использовать его каждый раз при переустановке View.

Добавить скругленный угол

Теперь пришло время создать закругленный угол.

func createRoundCorner(_ radius: CGFloat) {
    cornerRadius = radius
    super.createRoundCorner(radius)
    backgroundView.createRoundCorner(radius - borderWidth)
}

Каждый раз, когда мы устанавливаем радиус или backgroundColor, мы вызываем setupView. Таким образом gradientLayer а также backgroundView добавляются много раз. Сохраняйте экземпляр и удаляйте его каждый раз при настройке просмотра.

Добавить ширину границы

Но граница градиента не появляется. Ширина границы по-прежнему равна нулю. Нам нужно присвоить ненулевое значение borderWidth а также setupView опять таки.

func createBorder(_ width: CGFloat) {
    borderWidth = width
    setupView()
}

Результат

Взгляните на мой завершенный код для этой библиотеки на knGradientBorderButton
В этом проекте я использую свою библиотеку автоматической разметки. Вы можете найти это здесь: knConstraints

Не стесняйтесь комментировать, предлагать, создавать пул-реквесты или открывать проблемы.

Наслаждайтесь кодированием.

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *