代码之家  ›  专栏  ›  技术社区  ›  Nitesh

水平渐变到UIView

  •  0
  • Nitesh  · 技术社区  · 7 年前

    我试图通过以下方式将水平渐变添加到UIView

    extension UIView {
        func insertHorizontalGradient(_ color1: UIColor, _ color2: UIColor) {
            let gradient = CAGradientLayer()
            gradient.colors = [color1.cgColor, color2.cgColor]
            gradient.transform = CATransform3DMakeRotation(CGFloat.pi / 2, 0, 0, 1)
            gradient.frame = bounds
            layer.insertSublayer(gradient, at: 0)
        }
    }
    
    
        if let color1 = UIColor(hexString: "364190"), let color2 = UIColor(hexString: "699cf5"){
            self.statusBarView.insertHorizontalGradient(color1, color2)
        }
    
        if let color1 = UIColor(hexString: "182395"), let color2 = UIColor(hexString: "5497f0"){
            self.navigationBarView.insertHorizontalGradient(color1, color2)
        }
    

    但在iPhone 6Plus上,它并没有应用于整个UIView。但在iPhone 6上它是完美的。

    enter image description here

    3 回复  |  直到 7 年前
        1
  •  4
  •   Sulthan    6 年前

    每次视图框架更改时,都必须更新渐变。对它使用扩展不是最好的解决方案,因为您必须重写 UIView.layoutSubviews 总共 UIView 使用它的实例。相反,可以将图层包装到视图中:

    @IBDesignable
    public class GradientView: UIView {
        private func createGradient() -> CAGradientLayer {
            let gradient = CAGradientLayer()
            gradient.transform = CATransform3DMakeRotation(.pi / 2, 0, 0, 1)
            gradient.frame = bounds
            layer.insertSublayer(gradient, at: 0)
            return gradient
        }
    
        private var gradient: CAGradientLayer?
    
        @IBInspectable
        public var color1: UIColor? {
            didSet {
                updateColors()
            }
        }
    
        @IBInspectable
        public var color2: UIColor? {
            didSet {
                updateColors()
            }
        }
    
        required public init?(coder: NSCoder) {
            super.init(coder: coder)
            gradient = createGradient()
            updateColors()
        }
    
        override public init(frame: CGRect) {
            super.init(frame: frame)
            gradient = createGradient()
            updateColors()
        }
    
        override public func layoutSubviews() {
            super.layoutSubviews()
            gradient?.frame = bounds
        }
    
        private func updateColors() {
            guard
                let color1 = color1,
                let color2 = color2
            else {
                return
            }
    
            gradient?.colors = [color1.cgColor, color2.cgColor]
        }
    }
    

    然后:

    extension UIView {
        func insertHorizontalGradient(_ color1: UIColor, _ color2: UIColor) -> GradientView {
            let gradientView = GradientView(frame: bounds)
            gradientView.color1 = color1
            gradientView.color2 = color2
            gradientView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    
            self.insertSubview(gradientView, at 0)
            return gradientView
        }
    }
    

    注意我已经提出了 @IBDesignable ,两种颜色 @IBInspectable 因此,你实际上可以预览你的故事板/XIB中的梯度。

        2
  •  1
  •   Jack    7 年前

    相反 gradient.frame = bounds

    尝试

     gradient.frame = CGRect(x: bounds.origin.x , y: bounds.origin.y, width: UIScreen.main.bounds.width , height: bounds.height)
    

    因为你的视野覆盖了整个宽度 &这可防止 viewDidLayoutSubviews 多次通话

        3
  •  1
  •   Shehata Gamal    7 年前

    你得把它叫进去 viewDidLayoutSubviews 因为它包含正确的框架 viewDidLoad ,还要确保多次调用此函数,因此要么将代码包装在一个bool中,要么只在其中设置渐变帧