Основная проблема заключается в том, что слой градиента расположен сверху кнопки. Вторичная проблема (о которой вы еще не упомянули) заключается в том, что если вы поворачиваете устройство, оно не будет реагировать на изменения в кадре.
Лучшее решение - определить GradientView
, подложка которого , продиктованный его layerClass
, является CAGradientLayer
. Таким образом (а) он всегда будет ниже кнопки; и (b) он автоматически адаптируется к frame
изменениям (и делает это изящно более изящно во время анимаций, чем layoutSubviews
или viewDidLayoutSubviews
подходы тоже):
@IBDesignable
class GradientView: UIView {
override class var layerClass: AnyClass { return CAGradientLayer.self }
private var gradientLayer: CAGradientLayer { return layer as! CAGradientLayer }
@IBInspectable var startColor: UIColor = .white { didSet { updateGradient() } }
@IBInspectable var endColor: UIColor = #colorLiteral(red: 0.5019607843, green: 0.8078431373, blue: 1, alpha: 1) { didSet { updateGradient() } }
@IBInspectable var startPoint: CGFloat = 0 { didSet { updateGradient() } }
@IBInspectable var endPoint: CGFloat = 0.4 { didSet { updateGradient() } }
override init(frame: CGRect = .zero) {
super.init(frame: frame)
updateGradient()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
updateGradient()
}
}
private extension GradientView {
func updateGradient() {
gradientLayer.colors = [startColor, endColor].map { $0.cgColor }
gradientLayer.startPoint = CGPoint(x: 0, y: startPoint)
gradientLayer.endPoint = CGPoint(x: 0, y: endPoint)
}
}
С этим @IBDesignable
Затем вы можете установить базовый класс для представления вашего контроллера представления равным GradientView
, и он будет отображаться под кнопкой и будет правильно отображаться в Интерфейсном Разработчике. Например, щелкните в фоновом режиме и go на вкладке «Identity Inspector» на самой правой панели и установите «Class» в разделе «Custom Class»:
Вы можете изменить начальные / конечные цвета и начальные / конечные точки прямо в IB, если хотите, выбрав панель «Инспектор атрибутов» справа:
Очевидно, что если вы поступите таким образом, вам вообще не придется играть со слоем вида в viewDidLoad
. Но если вы хотите изменить это программно, вы можете сделать что-то вроде:
override func viewDidLoad() {
super.viewDidLoad()
if let view = view as? GradientView {
view.startColor = .black
view.endColor = .red
}
}
Но я бы лично установил цвета (или что-то еще) прямо в IB. И я бы оставил весь код «View Configuration» в классе UIView
, к которому он принадлежит, а не в контроллере View.