【问题标题】:Applying gradient background for UIView using auto layout使用自动布局为 UIView 应用渐变背景
【发布时间】:2016-09-19 12:17:39
【问题描述】:

我扩展了 UIView 添加了 addGradientWithColor() 方法来获取渐变背景:

 extension UIView {
   func addGradientWithColor() {
     let gradient = CAGradientLayer()
     gradient.frame = self.bounds
     gradient.colors = [gradientEndColor.CGColor,  gradientStartColor.CGColor]
     gradient.startPoint = CGPointMake(1,0)
     gradient.endPoint = CGPointMake(0.2,1)
    self.layer.insertSublayer(gradient, atIndex: 0)
  } } 

我的问题是当我运行横向模式时,UIView 没有被拉伸

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.view.addGradientWithColor() }

我尝试调用 viewDidLayoutSubviews() 但它无法正常工作

这是屏幕截图:

删除 viewDidLayoutSubviews() 后

【问题讨论】:

  • 你检查过这个ios8-auto-layout-and-gradient
  • 为什么你不继承 UIView 并覆盖 drawRect 方法。在该方法中,只需添加渐变。然后在 UIView 中添加您需要的约束即可。
  • @rob180 谢谢。是的,但没有解决我的问题
  • @tomCobo 谢谢你的建议,我会试试的
  • @tomCobo 谢谢你的建议是最好的。请给它作为答案

标签: ios objective-c uiview swift3 cagradientlayer


【解决方案1】:

您可以继承 UIView 并覆盖添加渐变的 drawRect 方法。

更新到 Swift 4


class GradientView: UIView {

    private let gradient : CAGradientLayer = CAGradientLayer()
    private let gradientStartColor: UIColor
    private let gradientEndColor: UIColor

    init(gradientStartColor: UIColor, gradientEndColor: UIColor) {
        self.gradientStartColor = gradientStartColor
        self.gradientEndColor = gradientEndColor
        super.init(frame: .zero)
    }

    required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }

    override func layoutSublayers(of layer: CALayer) {
        super.layoutSublayers(of: layer)
        gradient.frame = self.bounds
    }

    override public func draw(_ rect: CGRect) {
        gradient.frame = self.bounds
        gradient.colors = [gradientEndColor.cgColor, gradientStartColor.cgColor]
        gradient.startPoint = CGPoint(x: 1, y: 0)
        gradient.endPoint = CGPoint(x: 0.2, y: 1)
        if gradient.superlayer == nil {
            layer.insertSublayer(gradient, at: 0)
        }
    }
}

创建 UIView 后,您只需将约束添加到该视图。

【讨论】:

  • 我要加if (!self.gradient.superlayer) { self.layer.insertSublayer(self.gradient, atIndex: 0) }
  • if self.gradient.superlayer != nil { 应该是if self.gradient.superlayer == nil {
  • 确定是的。谢谢@thijsonline
  • UIColor 对我不起作用,我不得不改用 CGColor。
【解决方案2】:

您可以保存对图层的引用,并在视图layoutSublayersOfLayer 方法中调整它的框架。这可以在 UIView 子类中外包:

class GradientView: UIView {

private let gradient : CAGradientLayer = CAGradientLayer()

/**
 displays a gradient on the view
 */
func addGradient() {

    self.gradient.frame     = self.bounds
    self.gradient.colors    = [gradientEndColor.CGColor, gradientStartColor.CGColor]
    gradient.startPoint     = CGPointMake(1,0)
    gradient.endPoint       = CGPointMake(0.2,1)        
    self.layer.insertSublayer(self.gradient, atIndex: 0)
}

/**
 resizes the gradient with the view size
 */
override func layoutSublayers(of layer: CALayer) {
    super.layoutSublayers(of: layer)
    self.gradient.frame = self.bounds
}
}

【讨论】:

    【解决方案3】:

    图层不会自行自动调整大小。要解决此问题,您应该更改图层框架。这是一种实现方式:

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        //Update you're layer based on the new frame
        self.view.addGradientWithColor()
    
     }
    

    【讨论】:

    • 在我的情况下添加了 viewdidlayoutsubviews() 方法。我在同一个视图中得到两个渐变视图。我在问题本身中附上了屏幕截图
    【解决方案4】:

    受此处解决方案的启发,我创建了以下类。

    用法示例:

    // Simple usage. From clear to black.
    let gradientView1 = GradientView(colors: [.clear, .black])
    
    // Tweak locations. Here the gradient from red to green will take 30% of the view.
    let gradientView2 = GradientView(colors: [.red, .green, .blue], locations: [0, 0.3, 1])
    
    // Create your own gradient.
    let gradient = CAGradientLayer()
    gradient.colors = [UIColor.red.cgColor, UIColor.blue.cgColor]
    let gradientView3 = GradientView(gradient: gradient)
    

    班级:

    import UIKit
    
    /**
     * View with a gradient layer.
     */
    class GradientView: UIView {
    
        let gradient : CAGradientLayer
    
        init(gradient: CAGradientLayer) {
            self.gradient = gradient
            super.init(frame: .zero)
            self.gradient.frame = self.bounds
            self.layer.insertSublayer(self.gradient, at: 0)
        }
    
        convenience init(colors: [UIColor], locations:[Float] = [0.0, 1.0]) {
            let gradient = CAGradientLayer()
            gradient.colors = colors.map { $0.cgColor }
            gradient.locations = locations.map { NSNumber(value: $0) }
            self.init(gradient: gradient)
        }
    
        override func layoutSublayers(of layer: CALayer) {
            super.layoutSublayers(of: layer)
            self.gradient.frame = self.bounds
        }
    
        required init?(coder: NSCoder) { fatalError("no init(coder:)") }
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-19
      • 1970-01-01
      • 2015-04-23
      • 1970-01-01
      • 1970-01-01
      • 2010-10-25
      • 2018-06-09
      • 2020-08-27
      • 1970-01-01
      相关资源
      最近更新 更多