Как сделать uiview с помощью линейного градиента в Swift - PullRequest
0 голосов
/ 05 августа 2020

У меня в фигме такой стиль: background: linear-gradient (155.98deg, # F5FEFF 0%, # C5F8FF 0%, rgba (106, 164, 189, 0.5) 47.57%, # 0E8B9 C 88.75% ), #FFFFFF; мне нужно сделать мой uiview как linear-gradient

Ответы [ 2 ]

0 голосов
/ 06 августа 2020

Основная идея c состоит в том, чтобы настроить CAGradientLayer с массивом colors и locations. Если вам нужен диагональный градиент, укажите также startPoint и endPoint.

Но вам нужно расшифровать эту Фигму CSS. Первый параметр linear-gradient - это угол. Линейные градиенты в iOS измеряются не в углах, а с startPoint и endPoint, оба из которых являются ссылками CGPoint, где 0, 0 представляет верхний левый угол обзора, а 1, 1 представляет нижний правый угол. Ваш угол 155.98deg предполагает, что вы ищете градиент «от верхнего левого угла к нижнему правому», который будет иметь startPoint из 0, 0 и endPoint из 1, 1. (Точное соответствие между углом и этими CGPoint значениями будет зависеть от соотношения сторон рассматриваемого вида.)

Следующий параметр linear-gradient - это массив кортежей цветов и местоположения. Solid цвета представлены в шестнадцатеричных строках. Полупрозрачные цвета представлены целыми числами rgb. Таким образом, #F5FEFF 0% находится в позиции 0.0, а цвет 0xf5 для красного, 0xfe для зеленого и 0xff для синего. Вам нужно разделить все эти числа на 0xff (или 255). (Литерал цвета Xcode сделает это преобразование за вас.) А 0% в конце строки - это относительное расположение этого цвета в градиенте (где 0% - начало градиента, а 100% - конец). . Это хорошо коррелирует со свойством CAGradientLayer locations (хотя числа% представлены как значения от 0 до 1).

rgba(106, 164, 189, 0.5) 47.57% - это значения красного, зеленого и синего цветов 106, 164 и 189 соответственно (каждый разделен на 255). 0,5 - это альфа 50%. А 47,57 - это позиция (47,57% пути по градиенту).

В любом случае, чтобы отобразить это, определите массив цветов, массив позиций, а также начало и конец градиента:

@IBDesignable class GradientView: UIView {
    override class var layerClass: AnyClass { CAGradientLayer.self }
    var gradientLayer: CAGradientLayer { layer as! CAGradientLayer }

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

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

    func configure() {
        gradientLayer.colors = [#colorLiteral(red: 0.9607843137, green: 0.9960784314, blue: 1, alpha: 1), #colorLiteral(red: 0.7725490196, green: 0.9725490196, blue: 1, alpha: 1), #colorLiteral(red: 0.4156862745, green: 0.6431372549, blue: 0.7411764706, alpha: 0.5), #colorLiteral(red: 0.05490196078, green: 0.5450980392, blue: 0.6117647059, alpha: 1)].map { $0.cgColor }
        gradientLayer.locations = [0, 0, 0.4757, 0.8875]
        gradientLayer.startPoint = CGPoint(x: 0, y: 0)
        gradientLayer.endPoint = CGPoint(x: 1, y: 1)
    }
}

Если вы хотите увидеть шестнадцатеричное или целочисленное представление этих цветов, просто дважды щелкните цвет и нажмите «Другое», чтобы увидеть представления RGB. Например, я дважды щелкнул второй цвет и вижу значение #C5F8FF:

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

Пара заключительных наблюдений:

  • Обратите внимание, я не просто добавил CAGradientLayer и установил его фрейм. Вместо этого я создал вид, поддерживающий слой которого представляет собой градиент. Таким образом, если размер представления изменяется из-за ограничений (или если вы анимируете изменение размера), размер CAGradientLayer также изменяется динамически.

  • Я сделал это @IBDesignable чтобы я мог видеть это в раскадровке. Это не обязательно, но полезно при использовании раскадровок.

  • Интересно, действительно ли ваш дизайнер имел в виду, что #F5FEFF и #C5F8FF должны находиться в позиции 0%. Я подозреваю, что это была ошибка. (В Figma слишком легко иметь несколько точек данных цвета в градиенте, перекрывающиеся друг с другом либо на 0%, либо на 100%.)

  • Указанный вами CSS не выглядят синтаксически правильно. Примечательно, что я не знаю, что делать с этим #FFFFFF плавающим в конце (а ваши точки градиента не go полностью до 100%). Но я не думаю, что мне нужно знать ваше полное намерение здесь ... вы можете просто обновить массивы CAGradientLayer colors и locations по своему усмотрению. Просто убедитесь, что у них одинаковое количество записей.

  • Как вы заметили, если вы нажмете на крайнюю правую вкладку «Код» на панели справа в Figma, вы сможете см. фрагмент кода iOS. Я бы опасался использовать этот код дословно в вашем приложении, потому что он (а) не будет использовать описанный выше подкласс UIView, нарушая его размер, если представление изменит размер или будет анимировано; и (б) он будет использовать жестко запрограммированные значения, тогда как вы обычно хотите использовать ограничения для определения макетов в пределах iOS. Используйте этот фрагмент кода для вдохновения, предложений возможных API и т. Д. c., Но я бы не стал использовать именно этот код. Как и все автоматически сгенерированные фрагменты кода, предлагаемый Figma код iOS не идеален.

0 голосов
/ 05 августа 2020
let layerGradient = CAGradientLayer()
layerGradient.colors = [hexStringToUIColor(hex: "yourhex").cgColor,  hexStringToUIColor(hex: "yourhex").cgColor]
layerGradient.startPoint = CGPoint(x: 0, y: 0.5)
layerGradient.endPoint = CGPoint(x: 1, y: 0.5)
layerGradient.frame = CGRect(x: 0, y: 0, width: yourView.bounds.width, height: yourView.bounds.height)
self.yourView.layer.addSublayer(layerGradient)

По сути, вы добавляете слой поверх вида, которому затем назначаете начальную и конечную точки и предоставляете цвета для использования.

Это функция, используемая для преобразования шестнадцатеричных строк в цвета

func hexStringToUIColor (hex:String) -> UIColor {
    var cString:String = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
    
    if (cString.hasPrefix("#")) {
        cString.remove(at: cString.startIndex)
    }
    
    if ((cString.count) != 6) {
        return UIColor.gray
    }
    
    var rgbValue:UInt64 = 0
    Scanner(string: cString).scanHexInt64(&rgbValue)
    
    return UIColor(
        red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
        green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
        blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
        alpha: CGFloat(1.0)
    )
}
...