Я использую PaintCode StyleKit для генерации кучи градиентов, но PaintCode экспортирует их как CGGradient
. Я хотел добавить эти градиенты layer
. Можно ли преобразовать CGGradient
в CAGradientLayer
?Преобразование CGGradient в CAGradientLayer
ответ
№ Пункт CAGradientLayer заключается в том, что вы можете описать ему желаемый градиент и нарисовать градиент для вас. Вы уже прошли этот шаг; у вас есть уже описал градиент, который вы хотите (в PaintCode вместо от CAGradientLayer), и вы уже имеете желаемый градиент. Таким образом, глупо для вас даже хотите использовать CAGradientLayer, поскольку, если вы собираетесь это сделать, почему вы использовали PaintCode в первую очередь? Просто нарисуйте сам CGGradient в изображение, представление или даже слой.
Частично верно, но когда вы создаете цельное приложение в PaintCode и хотите только один градиент, используемый в 'CAShapeLayer' (для анимации или что-то еще), это действительный запрос, чтобы иметь возможность получать цвета и места отдельно. Мы посмотрим на это. – Tricertops
Вы не можете получить цвета из CGGradient, но вы можете использовать одни и те же значения, чтобы установить свойства colors
и locations
CAGradientLayer. Возможно, это поможет вам изменить созданный класс PCGradient
, чтобы сохранить цвета и местоположения в виде NSArrays, которые вы можете передать в CAGradientLayer.
Это может быть важно, если у вас есть библиотека градиентов и только изредка нужно использовать градиент в одном из двух форматов.
Да, это возможно, но для преобразования из обычной системы координат (с значениями от 0 до ширины и значений y от 0 до высоты) требуется математическая математика для системы координат, используемой CAGradientLayer (со значениями x от 0 до 1 и значения y от 0 до 1). И для этого требуется еще одна математика (довольно сложная), чтобы получить наклон.
Расстояние от 0 до 1 для x будет зависеть от ширины исходного прямоугольника. И расстояние от 0 до 1 для y будет зависеть от высоты исходного прямоугольника. Итак:
let convertedStartX = startX/Double(width)
let convertedStartY = startY/Double(height)
let convertedEndX = endX/Double(width)
let convertedEndY = endY/Double(height)
let intermediateStartPoint = CGPoint(x:convertedStartX,y:convertedStartY)
let intermediateEndPoint = CGPoint(x:convertedEndX,y:convertedEndY)
Это работает, если ваш первоначальный прямоугольник был квадратным. Если нет, наклон линии, определяющей угол градиента, будет неправильным! Чтобы исправить это увидеть отличный ответ здесь: CAGradientLayer diagonal gradient
Если вы выбираете утилиту оттуда, то вы можете установить окончательные преобразованные начальные и конечные точки следующим образом, начиная с уже скорректированными значениями точки сверху:
let fixedStartEnd:(CGPoint,CGPoint) = LinearGradientFixer.fixPoints(start: intermediateStartPoint, end: intermediateEndPoint, bounds: CGSize(width:width,height:height))
let myGradientLayer = CAGradientLayer()
myGradientLayer.startPoint = fixedStartEnd.0
myGradientLayer.endPoint = fixedStartEnd.1
Вот код для полного Struct, который можно использовать для хранения данных градиента и получить обратно CGGradients или CAGradientLayers при необходимости:
import UIKit
struct UniversalGradient {
//Doubles are more precise than CGFloats for the
//calculations needed to convert start and end
//to CAGradientLayers 1...0 format
var startX: Double
var startY: Double
var endX: Double
var endY: Double
let options: CGGradientDrawingOptions = [.drawsBeforeStartLocation, .drawsAfterEndLocation]
//for CAGradientLayer
var colors: [UIColor]
var locations: [Double]
//computed conversions
private var myCGColors: [CGColor] {
return self.colors .map {color in color.cgColor}
}
private var myCGFloatLocations: [CGFloat] {
return self.locations .map {location in CGFloat(location)}
}
//computed properties
var gradient: CGGradient {
return CGGradient(colorsSpace: nil, colors: myCGColors as CFArray, locations: myCGFloatLocations)!
}
var start: CGPoint {
return CGPoint(x: startX,y: startY)
}
var end: CGPoint {
return CGPoint(x: endX,y: endY)
}
//can't use computed property here
//since we need details of the specific environment's bounds to be passed in
//so this will be an instance function
func gradientLayer(width: CGFloat, height: CGFloat) -> CAGradientLayer {
//convert location x and y values from full coordinates to 0...1 for start and end
//this works great for position, but it gets the slope incorrect if the view is not square
//this is because the gradient is not drawn with the final scale
//it is drawn while the view is square, and then it gets stretched, changing the angle
//https://stackoverflow.com/questions/38821631/cagradientlayer-diagonal-gradient
let convertedStartX = startX/Double(width)
let convertedStartY = startY/Double(height)
let convertedEndX = endX/Double(width)
let convertedEndY = endY/Double(height)
let intermediateStartPoint = CGPoint(x:convertedStartX,y:convertedStartY)
let intermediateEndPoint = CGPoint(x:convertedEndX,y:convertedEndY)
let fixedStartEnd:(CGPoint,CGPoint) = LinearGradientFixer.fixPoints(start: intermediateStartPoint, end: intermediateEndPoint, bounds: CGSize(width:width,height:height))
let myGradientLayer = CAGradientLayer()
myGradientLayer.startPoint = fixedStartEnd.0
myGradientLayer.endPoint = fixedStartEnd.1
myGradientLayer.locations = self.locations .map {location in NSNumber(value: location)}
myGradientLayer.colors = self.colors .map {color in color.cgColor}
return myGradientLayer
}
}
- 1. CGGradient в CGPath
- 2. Добавление CGGradient в качестве подслоя в UILabel скрывает текст метки
- 3. Загрузка изображения или использование CGGradient более эффективно?
- 4. UIView CGGradient, привязанный к нарисованному «кадру»
- 5. CAGradientLayer падает с «EXC_BAD_ACCESS» в простейшем прецеденте
- 6. Добавить простой CGGradient в UINavigationBar
- 7. Обрезание CGGradient до CGPath
- 8. CGGradient не сразу рисуется
- 9. CAGradientLayer в UITableViewCell
- 10. Создайте CGGradient с динамического оттенкаЦвет
- 11. CGGradient проблема с быстрыми 3
- 12. CGGradient не работает на UINavigationBar
- 13. Плохой рисунок CGGradient с альфой
- 14. Случайно сгенерированный CGGradient wont display
- 15. Как добавить CAGradientLayer в CAShapeLayer?
- 16. горизонтального CAGradientLayer в прошивкой 7,0
- 17. CAGradientLayer с углом
- 18. Как использовать CAGradientLayer?
- 19. Как переключить CAGradientLayer?
- 20. CAGradientLayer дает EXC_BAD_ACCESS?
- 21. Circular CAGradientLayer Mask
- 22. CAGradientLayer иногда не отображается
- 23. CAGradientLayer не работает
- 24. Отображение SCNScene над CAGradientLayer
- 25. CAGradientLayer только фон
- 26. CAGradientLayer не отображается?
- 27. UISearchController add CAGradientLayer
- 28. CAGradientLayer не авторезистирует
- 29. CAGradientLayer отправить обратно
- 30. Пользовательский CAGradientLayer не анимируется
ли вы * необходимости *, чтобы преобразовать его в какой-то конкретной причине? Вы можете нарисовать CGGradient в UIView. – EmilioPelaez
Исправление: PaintCode генерирует класс 'PCGradient', который обертывает' CGGradientRef'. – Tricertops