嗨,我是Swift和Xcode的新手,只是学习基础知识。我已经以编程方式添加了一个渐变层,然后使用主情节提要板添加了UIButton
并为其分配了出口,但是当我运行代码时,渐变层会显示但按钮会显示,但是,当我删除渐变层时,显示UIButton
。附件是同时使用渐变和代码时将发生的情况的屏幕截图,并会附上a。
class ViewController: UIViewController {
let layer = CAGradientLayer()
@IBOutlet weak var pressMeButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
layer.frame = view.bounds
layer.colors = [UIColor.white.cgColor, UIColor(red: 128/255, green: 206/255, blue: 255/255, alpha: 1).cgColor]
layer.startPoint = CGPoint(x: 0, y: 0)
layer.endPoint = CGPoint(x: 0, y: 0.4)
view.layer.addSublayer(layer)
pressMeButton.layer.cornerRadius = 25.0
pressMeButton.layer.borderWidth = 0.8
pressMeButton.layer.borderColor = UIColor.black.cgColor
pressMeButton.setTitle("Press Me", for: .normal)
pressMeButton.setTitleColor(.black, for: .normal)
}
}
带有情节提要的代码显示了按钮的放置,没有按钮的模拟器:
您是在视图顶部添加图层,而您之前已经添加了UIButton。因此该层与UIButton重叠。
您需要在控制器的主视图中添加一个容器视图,然后在其上添加渐变层。
主要问题是渐变层位于按钮顶部。第二个问题(您尚未提到)是,如果旋转设备,它将无法响应框架中的更改。
最佳解决方案是定义一个GradientView
,其衬里层由其layerClass
决定为layerClass
。这样(a)它将始终位于按钮下方; (b)它会自动适应CAGradientLayer
的更改(并且在动画过程中也比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
,它将在按钮下方呈现该基类,并在Interface Builder中正确显示。例如,单击背景视图,然后转到最右侧面板中的“身份检查器”选项卡,然后在“自定义类别”部分中设置“类别”:
GradientView
如果需要,您可以在IB中直接更改开始/结束颜色和开始/结束点,方法是选择右侧的“属性检查器”面板:
很显然,如果您采用这种方式,则完全不需要在中浏览视图的图层。但是,如果要以编程方式更改它,可以执行以下操作:
viewDidLoad
但是我亲自在IB中设置颜色(或其他颜色)。然后,我将所有“视图配置”代码保留在其所属的override func viewDidLoad() {
super.viewDidLoad()
if let view = view as? GradientView {
view.startColor = .black
view.endColor = .red
}
}
类中,而不是在视图控制器中。
感谢所有帮助,但最终我创建了一个带有用于进行渐变的参数的玻璃,以及另一个带有用于某些颜色的参数的玻璃,然后能够将它们拉入viewLoad。