CAGradientLayer не применяется к полному представлению в программно созданном пользовательском интерфейсе

#ios #swift #calayer #bounds #cagradientlayer

#iOS #swift #calayer #границы #cagradientlayer

Вопрос:

Я работаю над проектом iOS, который создает все свои пользовательские интерфейсы программно. Не раскадровки.

Я хочу добавить градиент к фону пользовательского интерфейса UIViewController.

Я создал следующий метод расширения.

 extension UIView {
    
    func addGradient(colors: [UIColor]) {
        let gradientLayer = CAGradientLayer()
        gradientLayer.bounds = bounds
        gradientLayer.colors = colors.map { $0.cgColor }
        layer.insertSublayer(gradientLayer, at: 0)
    }
    
}
  

И я добавил градиент в viewDidLoad ViewController вот так.

 let topColor = UIColor(red: 0.28, green: 0.521, blue: 0.696, alpha: 1)
let bottomColor = UIColor(red: 0.575, green: 0.615, blue: 0.692, alpha: 1)
view.addGradient(colors: [topColor, bottomColor])
  

Но градиент не применяется ко всей ширине и высоте экрана.

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

Я распечатал границы представления, и оно показывает эти значения.

(0.0, 0.0, 375.0, 812.0)

Поэтому я не уверен, почему градиент все еще не покрывает полный вид.

Комментарии:

1. в представлении Сделал макет, обновил рамку градиента, не следует устанавливать границы, вместо этого используйте рамку

2. @PrashantTukadiya Я тоже это пробовал. По-прежнему ничего не меняет.

3. programmingios.net/premature-layout

4. @matt Я переместил код настройки градиента в viewDidLayoutSubviews , но по какой-то причине он все еще не работает. ДЕМОНСТРАЦИЯ

Ответ №1:

В addGradient(colors:) методе установите gradientLayer's frame вместо bounds , т.е.

 func addGradient(colors: [UIColor]) {
    let gradientLayer = CAGradientLayer()
    gradientLayer.frame = bounds //here.....

    //rest of the code...
}
  

Кроме того, как было предложено, переместите свой код в viewDidLayoutSubviews() метод,

 override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    let topColor = UIColor(red: 0.28, green: 0.521, blue: 0.696, alpha: 1)
    let bottomColor = UIColor(red: 0.575, green: 0.615, blue: 0.692, alpha: 1)
    view.addGradient(colors: [topColor, bottomColor])
}
  

Это связано с тем, что gradient's frame должно меняться каждый раз, когда в view's макете происходят какие-либо изменения. Например, в книжной и альбомной ориентации.

Ответ №2:

Когда мы добавляем границы вида к рамке градиентного слоя, мы должны обновить фрейм в viewDidLayoutSubviews. Для меня это работает нормально, у меня сработало следующее

 override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    
    self.gradient.frame = containerView.bounds
}
  

containerView — это представление, в котором я устанавливаю градиентный слой.