带有渐变的 UIView 在点击按钮时不会改变颜色
UIView with gradient not changing colors when button is tapped
当用户单击按钮时,它会随机化用于在大圆圈中创建渐变的颜色。它下面是两个小圆圈,显示用于渐变的纯色。它们在开始时都正确显示(主圆是随机小圆颜色的渐变)但是当我点击按钮时,只有小圆改变颜色;大圆圈保持相同的渐变颜色。
扩展和视图控制器:
extension UIView {
func setupGradientBackground(colorOne: UIColor, colorTwo: UIColor) {
let gradientLayer: CAGradientLayer = CAGradientLayer()
gradientLayer.colors = [colorOne.cgColor, colorTwo.cgColor]
gradientLayer.locations = [0.0, 1.0]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.0)
gradientLayer.frame = self.bounds
self.layer.insertSublayer(gradientLayer, at: 0)
}
}
extension UIColor {
static var random: UIColor {
return UIColor(red: .random(in: 0...1), green: .random(in: 0...1), blue: .random(in: 0...1), alpha: 1.0)
}
}
class GradientController: UIViewController {
let gradientView = GradientView()
let leftGradientColor: UIColor = .random
let rightGradientColor: UIColor = .random
}
override func viewDidLoad() {
super.viewDidLoad()
view = gradientView
newGradient()
}
func newGradient() {
gradientView.mainCircleView.setupGradientBackground(colorOne: leftGradientColor, colorTwo: rightGradientColor)
gradientView.colorCircleLeftView.backgroundColor = leftGradientColor
gradientView.colorCircleRightView.backgroundColor = rightGradientColor
gradientView.gradientGenerateButton.addTarget(self, action: #selector(randomGradient(sender:)), for: .touchUpInside)
}
@objc func randomGradient(sender: UIButton)
{
let leftGradient = UIColor.random
let rightGradient = UIColor.random
gradientView.colorCircleLeftView.backgroundColor = leftGradient
gradientView.colorCircleRightView.backgroundColor = rightGradient
//Here is where it's not changing colors. Doesn't seem like the VC recognizes it in this function
gradientView.mainCircleView.setupGradientBackground(colorOne: leftGradient, colorTwo: rightGradient)
}
查看:
class GradientView: UIView {
//circle's UIView code in Extensions
let mainCircleView = UIView().circleView(width: 380, height: 380)
let colorCircleLeftView = UIView().circleView(width: 40, height: 40)
let colorCircleRightView = UIView().circleView(width: 40, height: 40)
...
func setupLayout() {
...
}
}
我尝试将 mainCircleView
颜色更改为纯 UIColors,例如 gradientView.mainCircleView.setupGradientBackground(colorOne: .red, colorTwo: .orange)
以查看主圆是否更改为 func newGradient()
和 [=15] 中的那些颜色=].它仅更改 func newGradient()
我手动设置的内容,这意味着 VC 无法识别 @objc func
中的主圆,但我不知道如何修复它。 ..
感谢任何帮助!
单击 "Generate" 按钮时的样子(大圆圈应显示棕色和紫色):
渐变没有改变,因为您在现有渐变下方添加了新渐变
extension UIView {
func setupGradientBackground(colorOne: UIColor, colorTwo: UIColor) {
let gradientLayer: CAGradientLayer = CAGradientLayer()
...
// ⬇ There is a mistake.
self.layer.insertSublayer(gradientLayer, at: 0)
}
}
您应该用这个新的渐变来改变当前的渐变。或者在旧的上面插入一个新的。
用这个更新你的功能,你必须删除旧层然后插入新的子层。
解决方案 1:
func setupGradientBackground(colorOne: UIColor, colorTwo: UIColor) {
if let gradientLayer = (self.layer.sublayers?.compactMap { [=10=] as? CAGradientLayer })?.first {
gradientLayer.removeFromSuperlayer()
}
let gradientLayer: CAGradientLayer = CAGradientLayer()
gradientLayer.colors = [colorOne.cgColor, colorTwo.cgColor]
gradientLayer.locations = [0.0, 1.0]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.0)
gradientLayer.frame = self.bounds
self.layer.insertSublayer(gradientLayer, at: 0)
}
方案二:
func setupGradientBackground(colorOne: UIColor, colorTwo: UIColor) {
let gradientLayer = layer.sublayers?.first as? CAGradientLayer ?? CAGradientLayer()
gradientLayer.colors = [colorOne.cgColor, colorTwo.cgColor]
gradientLayer.locations = [0.0, 1.0]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.0)
gradientLayer.frame = self.bounds
guard gradientLayer.superlayer != self else {
return
}
layer.insertSublayer(gradientLayer, at: 0)
}
解决方案 3:
您可以将名称设置为您的 CAGradientLayer
,这将帮助您删除该特定图层。
func setupGradientBackground(colorOne: UIColor, colorTwo: UIColor) {
for layer in layer.sublayers ?? [] {
if layer.name == "GradientLayer" {
layer.removeFromSuperlayer()
}
}
let gradientLayer: CAGradientLayer = CAGradientLayer()
gradientLayer.colors = [colorOne.cgColor, colorTwo.cgColor]
gradientLayer.locations = [0.0, 1.0]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.0)
gradientLayer.name = "GradientLayer"
gradientLayer.frame = self.bounds
self.layer.insertSublayer(gradientLayer, at: 0)
}
设置后更改渐变层颜色
extension CALayer {
func updateGradientColors(_ colors:CGColor...) {
if let layer = sublayers?.first as? CAGradientLayer {
let frame = CGRect(origin: self.bounds.origin, size: CGSize(width: self.bounds.size.width, height: self.bounds.size.height))
layer.frame = frame
layer.colors = colors
}
}
}
当用户单击按钮时,它会随机化用于在大圆圈中创建渐变的颜色。它下面是两个小圆圈,显示用于渐变的纯色。它们在开始时都正确显示(主圆是随机小圆颜色的渐变)但是当我点击按钮时,只有小圆改变颜色;大圆圈保持相同的渐变颜色。
扩展和视图控制器:
extension UIView {
func setupGradientBackground(colorOne: UIColor, colorTwo: UIColor) {
let gradientLayer: CAGradientLayer = CAGradientLayer()
gradientLayer.colors = [colorOne.cgColor, colorTwo.cgColor]
gradientLayer.locations = [0.0, 1.0]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.0)
gradientLayer.frame = self.bounds
self.layer.insertSublayer(gradientLayer, at: 0)
}
}
extension UIColor {
static var random: UIColor {
return UIColor(red: .random(in: 0...1), green: .random(in: 0...1), blue: .random(in: 0...1), alpha: 1.0)
}
}
class GradientController: UIViewController {
let gradientView = GradientView()
let leftGradientColor: UIColor = .random
let rightGradientColor: UIColor = .random
}
override func viewDidLoad() {
super.viewDidLoad()
view = gradientView
newGradient()
}
func newGradient() {
gradientView.mainCircleView.setupGradientBackground(colorOne: leftGradientColor, colorTwo: rightGradientColor)
gradientView.colorCircleLeftView.backgroundColor = leftGradientColor
gradientView.colorCircleRightView.backgroundColor = rightGradientColor
gradientView.gradientGenerateButton.addTarget(self, action: #selector(randomGradient(sender:)), for: .touchUpInside)
}
@objc func randomGradient(sender: UIButton)
{
let leftGradient = UIColor.random
let rightGradient = UIColor.random
gradientView.colorCircleLeftView.backgroundColor = leftGradient
gradientView.colorCircleRightView.backgroundColor = rightGradient
//Here is where it's not changing colors. Doesn't seem like the VC recognizes it in this function
gradientView.mainCircleView.setupGradientBackground(colorOne: leftGradient, colorTwo: rightGradient)
}
查看:
class GradientView: UIView {
//circle's UIView code in Extensions
let mainCircleView = UIView().circleView(width: 380, height: 380)
let colorCircleLeftView = UIView().circleView(width: 40, height: 40)
let colorCircleRightView = UIView().circleView(width: 40, height: 40)
...
func setupLayout() {
...
}
}
我尝试将 mainCircleView
颜色更改为纯 UIColors,例如 gradientView.mainCircleView.setupGradientBackground(colorOne: .red, colorTwo: .orange)
以查看主圆是否更改为 func newGradient()
和 [=15] 中的那些颜色=].它仅更改 func newGradient()
我手动设置的内容,这意味着 VC 无法识别 @objc func
中的主圆,但我不知道如何修复它。 ..
感谢任何帮助!
单击 "Generate" 按钮时的样子(大圆圈应显示棕色和紫色):
渐变没有改变,因为您在现有渐变下方添加了新渐变
extension UIView {
func setupGradientBackground(colorOne: UIColor, colorTwo: UIColor) {
let gradientLayer: CAGradientLayer = CAGradientLayer()
...
// ⬇ There is a mistake.
self.layer.insertSublayer(gradientLayer, at: 0)
}
}
您应该用这个新的渐变来改变当前的渐变。或者在旧的上面插入一个新的。
用这个更新你的功能,你必须删除旧层然后插入新的子层。
解决方案 1:
func setupGradientBackground(colorOne: UIColor, colorTwo: UIColor) {
if let gradientLayer = (self.layer.sublayers?.compactMap { [=10=] as? CAGradientLayer })?.first {
gradientLayer.removeFromSuperlayer()
}
let gradientLayer: CAGradientLayer = CAGradientLayer()
gradientLayer.colors = [colorOne.cgColor, colorTwo.cgColor]
gradientLayer.locations = [0.0, 1.0]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.0)
gradientLayer.frame = self.bounds
self.layer.insertSublayer(gradientLayer, at: 0)
}
方案二:
func setupGradientBackground(colorOne: UIColor, colorTwo: UIColor) {
let gradientLayer = layer.sublayers?.first as? CAGradientLayer ?? CAGradientLayer()
gradientLayer.colors = [colorOne.cgColor, colorTwo.cgColor]
gradientLayer.locations = [0.0, 1.0]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.0)
gradientLayer.frame = self.bounds
guard gradientLayer.superlayer != self else {
return
}
layer.insertSublayer(gradientLayer, at: 0)
}
解决方案 3:
您可以将名称设置为您的 CAGradientLayer
,这将帮助您删除该特定图层。
func setupGradientBackground(colorOne: UIColor, colorTwo: UIColor) {
for layer in layer.sublayers ?? [] {
if layer.name == "GradientLayer" {
layer.removeFromSuperlayer()
}
}
let gradientLayer: CAGradientLayer = CAGradientLayer()
gradientLayer.colors = [colorOne.cgColor, colorTwo.cgColor]
gradientLayer.locations = [0.0, 1.0]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.0)
gradientLayer.name = "GradientLayer"
gradientLayer.frame = self.bounds
self.layer.insertSublayer(gradientLayer, at: 0)
}
设置后更改渐变层颜色
extension CALayer {
func updateGradientColors(_ colors:CGColor...) {
if let layer = sublayers?.first as? CAGradientLayer {
let frame = CGRect(origin: self.bounds.origin, size: CGSize(width: self.bounds.size.width, height: self.bounds.size.height))
layer.frame = frame
layer.colors = colors
}
}
}