Я пытаюсь установить фон на моем UIView
градиентом. В моем методе UIViewController
's viewDidLoad
есть следующее:
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [UIColor.blue70.cgColor, UIColor.blue60.cgColor, UIColor.blue70.cgColor]
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 1, y: 1 )
gradientLayer.frame = self.view.bounds
self.view.layer.insertSublayer(gradientLayer, at: 0)
Градиент отображается так, как ожидалось. Однако, когда я поворачиваю устройство, градиент не перерисовывается и больше не отображается должным образом. Вращение из портрета->пейзажа оставляет меня с пустой секцией справа или слева. Вращение из альбомной ориентации в портретную оставляет пустой раздел внизу. Я попытался переместить этот код в viewDidLayoutSubviews
, но это не решило проблему. Любые рекомендации о том, как это сделать?
Я бы порекомендовал добавить градиент в метод viewWillLayoutSubviews().
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
self.view.addGradiant()
}
Но теперь нам придется удалить старый слой при добавлении нового с новыми кадрами (на случай, если телефон вращается)
Затем мы можем сначала удалить слой и добавить новый, как в этом методе расширения.
extension UIView {
func addGradiant() {
let GradientLayerName = "gradientLayer"
if let oldlayer = self.layer.sublayers?.filter({$0.name == GradientLayerName}).first {
oldlayer.removeFromSuperlayer()
}
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [UIColor.blue.cgColor, UIColor.red.cgColor, UIColor.green.cgColor]
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 1, y: 1 )
gradientLayer.frame = self.bounds
gradientLayer.name = GradientLayerName
self.layer.insertSublayer(gradientLayer, at: 0)
}
}
Сделайте градиентный слой свойством контроллера представления.
let gradientLayer = CAGradientLayer()
Добавьте градиентный слой в viewDidLoad так же, как и вы.
Установите фрейм в viewWillLayoutSubviews
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
gradientLayer.frame = self.view.bounds
}
Неа. Пробовал. Та же проблема с перерисовкой.
Хотя вы можете сделать, как предлагают другие ответы, и обновить границы слоя градиента в viewDidLayoutSubviews
, более многоразовый способ сделать что-то — создать подкласс градиентного представления, который layerClass
является CAGradientLayer
. У такого представления будет автоматически изменен размер слоя, чтобы соответствовать виду (поскольку слой градиента теперь является вспомогательным слоем для представления, а не каким-либо подслоем), и вы можете использовать это представление где угодно, просто изменив класс вашего представления в файле пера. или раскадровка:
class GradientView: UIView {
var colors: [UIColor] = [.red, .white] {
didSet {
setup()
}
}
var locations: [CGFloat] = [0,1] {
didSet {
setup()
}
}
var startPoint: CGPoint = .zero {
didSet {
setup()
}
}
var endPoint: CGPoint = CGPoint(x: 1, y: 1) {
didSet {
setup()
}
}
override class var layerClass : AnyClass { return CAGradientLayer.self }
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
override func awakeFromNib() {
super.awakeFromNib()
setup()
}
private func setup() {
guard let layer = self.layer as? CAGradientLayer else {
return
}
layer.colors = colors.map { $0.cgColor }
layer.locations = locations.map { NSNumber(value: Double($0)) }
layer.startPoint = startPoint
layer.endPoint = endPoint
}
}
Ваша основная проблема заключается в том, что вы добавляете несколько слоев градиента внизу вашего представления, но будет виден только тот, который находится вверху. Что вам нужно, так это убедиться, что вы добавили только один градиентный слой и настроили его рамку в методе viewDidLayoutSubviews
gradientLayer.frame = view.bounds