Использование UIColor с CAShapeLayer
Я передаю цвет RGB в shapeLayer.fillColor
а также shapeLayer.strokeColor
и мой код не работает. Вот что я попробовал:
let shapeLayer = CAShapeLayer()
shapeLayer.fillColor = (UIColor(red: 57, green: 65, blue: 101, alpha: 1) as! CGColor)
shapeLayer.strokeColor = (UIColor(red: 57, green: 65, blue: 101, alpha: 1) as! CGColor)
Если я напишу свой цвет RGB как:
UIColor(red: 57, green: 65, blue: 101, alpha: 1)
Xcode дает мне предупреждение, чтобы изменить его на:
(UIColor(red: 57, green: 65, blue: 101, alpha: 1) as! CGColor)
Когда я запускаю предложенное Xcode исправление, мое приложение вылетает. Зачем?
3 ответа
First of all the parameters red
,green
, blue
а также alpha
must be in range from 0.0 to 1.0
Secondly, you must pass the cgColor
в CGLayer
например,
let color = UIColor(red: 57.0/255.0, green: 65.0/255.0, blue: 101.0/255.0, alpha: 1)
shapeLayer.fillColor = color.cgColor
shapeLayer.strokeColor = color.cgColor
Вы кастинг типа UIColor
как CGColor
это не правильно. И значения RGB должны быть в диапазоне от 0,0 до 1,0, проверьте код ниже.
let circlePath = UIBezierPath(arcCenter: CGPoint(x: bounds.origin.x+60,y: bounds.origin.y+107), radius: CGFloat(6), startAngle: CGFloat(0), endAngle:CGFloat(7), clockwise: true)
let shapeLayer = CAShapeLayer()
shapeLayer.path = circlePath.cgPath
circlePath.lineCapStyle = .round
let color = UIColor(red: 57.0/255.0, green: 65.0/255.0, blue: 101.0/255.0, alpha: 1).cgColor
shapeLayer.fillColor = color
shapeLayer.strokeColor = color
shapeLayer.lineWidth = 3.0
self.layer.addSublayer(shapeLayer)
Исправление вашего кода
Вы хотите что-то вроде этого:
let shapeLayer = CAShapeLayer()
shapeLayer.fillColor = UIColor(red: 57, green: 65, blue: 101, alpha: 1).cgColor
shapeLayer.strokeColor = UIColor(red: 57, green: 65, blue: 101, alpha: 1).cgColor
Как это устроено
Предупреждение о наследовании
Xcode предупреждает вас о том, что для этого назначения правильно, потому что вы назначаете UIColor
к CGColor
собственность, но предложение "исправить меня" неверно. (XCode может делать это, потому что он видит, что имена классов похожи, но не идентичны. Возможно, стоит подать радар.)
Одно из мест, где вы увидите это, - это кастомизация UITableViewCell
подкласс к базовому классу ячейки, но это не сработает здесь. CGColor
не наследуется от UIColor
и не делает UIColor
наследовать от CGColor
, CGColor является CFTypeRef
и UIColor наследуется от `NSObject.
Один из них не похож на другой
Теперь, почему эти цвета разные?
CG
расшифровывается как "Core Graphics" и находится на более низком уровне, чем UIKit, который определяет UIColor
учебный класс. Один цветной объект является частью UIKit и частью Core Graphics.
В документации сказано, что UIColor
является:
Объект, в котором хранятся данные о цвете и иногда непрозрачность (альфа-значение)."
Чуть дальше, обзор говорит, что UIColor представляет себя как CGColor
в заданном цветовом пространстве.
CGColor
с другой стороны, это:
Набор компонентов, которые определяют цвет, с цветовым пространством, определяющим, как их интерпретировать. "
Концептуально очень похоже, но не совсем то же самое. UIColor определяется в пространстве sRGBA ( как отмечено здесь), но CGColor
будет содержать информацию о том, в каком цветовом пространстве он находится.
Теперь используемый вами слой анимации является частью Core Animation, которая является еще одним фреймворком Apple. Базовая анимация не является частью UIKit, и она также не "поверх" UIKit, поэтому ее классы не используют UIColor
, Core Animation использует CGColor
для его представления цветов.
UIColor
Это так легко реализовать, и мы в любом случае находимся на UIKit-земле. Как мы можем настроить CALayer
и друзья во время работы в нашем UIView
с и UIViewController
s? К счастью, UIColor
подвергает CGColor
версия сама по себе, с .cgColor
имущество.
Примечание о цветовых пространствах
Некоторые другие ответы отмечают, что вам нужно передавать значения от 0,0 до 1,0. Это действительно так, но важно отметить, что с iOS 10 Apple добавила в iOS некоторые более широкие цветовые возможности.
Это означает, что на самом деле можно передавать значения меньше 0,0 и больше 1,0. Из документации UIColor:
При работе в расширенном цветовом пространстве значения цвета не ограничиваются, чтобы вписаться в цветовую гамму, а это означает, что значения компонентов могут быть меньше 0,0 или больше 1,0. При отображении на дисплее sRGB такие цвета находятся за пределами гаммы и не будут отображаться точно.
Возможно, вам сейчас не нужно беспокоиться о цветовых пространствах, но важно понимать основы, если вы хотите сделать что-то большее, чем показывать цвет на экране. (Генерация инвертированных или дополнительных цветов - некоторые примеры.)
Сессия 712 из WWDC 2016 (ссылка) подробно описывает этот новый API, и я рекомендую вам взглянуть на него, как только вы освоитесь с основами.
Наконец, есть техническая записка Apple (TN2313), в которой это обсуждается более подробно, чем я мог себе представить. Если вы хотите узнать больше о цветах и цветовых пространствах в iOS и macOS, прочитайте техническую заметку под названием "Лучшие практики для управления цветом в OS X и iOS".