Как нарисовать кнопку с градиентной рамкой?
На прошлой неделе мой партнер показал мне свой дизайн для нашего приложения. Все отлично, легко реализуется с помощью некоторых настраиваемых элементов управления, кроме этого.
Кнопка с градиентной рамкой. Никогда не пробуйте это раньше. До сих пор я только что создавал градиентные фоновые представления 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
Не стесняйтесь комментировать, предлагать, создавать пул-реквесты или открывать проблемы.
Наслаждайтесь кодированием.