简体   繁体   English

旋转时从子视图中删除渐变

[英]Remove gradient from subview on rotation

I can remove the gradient from the subview fine, But If a button is added to the subview I can not remove the gradient layer.我可以很好地从子视图中删除渐变,但是如果在子视图中添加了一个按钮,我将无法删除渐变图层。 How can I Remove gradient from subview on rotation.如何在旋转时从子视图中删除渐变。

Here is the code for the View Controller.这是视图控制器的代码。

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var buttonOutlet: UIButton!
    @IBOutlet weak var labelOutlet: UILabel!
    @IBOutlet weak var mySubView: UIView!   
    @IBOutlet weak var mySubView2: UIView!
    @IBOutlet weak var mySubView3: UIView!

    override func viewDidLayoutSubviews() {
         addGradient()
    }

    fileprivate func addGradient() {
        mySubView.mainGradientBackground()
        mySubView2.subGradientBackground()
        mySubView3.subGradientBackground()
        labelOutlet.labelTextfieldShadow()
        buttonOutlet.buttonGradientBackground(cornerRadius: 10, shadowRadius: 3)
    }

     /// This will let you know when the device rotates.
    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
       if UIDevice.current.orientation.isValidInterfaceOrientation {

            removeSublayer(mySubView, layerIndex: 0)
            removeSublayer(mySubView, layerIndex: 0)

            removeSublayer(mySubView2, layerIndex: 0)
            removeSublayer(mySubView2, layerIndex: 0)

            removeSublayer(mySubView3, layerIndex: 0)
            removeSublayer(mySubView3, layerIndex: 0)

            removeSublayer(buttonOutlet, layerIndex: 0)
            removeSublayer(buttonOutlet, layerIndex: 0)

            removeSublayer(labelOutlet, layerIndex: 0)
        }
    }


    func removeSublayer(_ view: UIView, layerIndex index: Int) {
        guard let sublayers = view.layer.sublayers else {
            print("The view does not have any sublayers.")
            return
        }
        if sublayers.count > index {
            view.layer.sublayers!.remove(at: index)
        } else {
            print("There are not enough sublayers to remove that index.")
        }
    }
}

This is the Gradient Extension used to color any views I need.这是用于为我需要的任何视图着色的渐变扩展。

import Foundation
import UIKit

extension UIView {
    /// Use this to set a gradient for the background.
    /// = This is a gradient with no shadow.
    func mainGradientBackground() {
        let color = Color()

        let leading = color.backgroundLeading
        let trailing = color.backgroundTrailing

        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = bounds
        gradientLayer.colors = [leading, trailing]
        gradientLayer.locations = [0,0.3]
        gradientLayer.startPoint = CGPoint(x: 0.05, y: 0.5)
        gradientLayer.endPoint = CGPoint(x: 0.75, y: 0.5)

        layer.insertSublayer(gradientLayer, at: 0)
    }

    /// Use this to set a gradient for the background.
    /// = This is a gradient with a shadow.
     func subGradientBackground() {

        let corner: CGFloat = 15
        let color = Color()

        let leading = color.subBackgroundLeading
        let trailing = color.subBackgroundTrailing
        let borderColor = color.subBorderColor

        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = bounds
        gradientLayer.colors = [leading, trailing]
        gradientLayer.locations = [0,0.3,1]
        gradientLayer.startPoint = CGPoint(x: 0.05, y: 0.5)
        gradientLayer.endPoint = CGPoint(x: 0.75, y: 0.5)
        gradientLayer.borderColor = borderColor
        gradientLayer.borderWidth = 4
        gradientLayer.cornerRadius = corner
        layer.insertSublayer(gradientLayer, at: 0)

        let subLayer = CALayer()
        subLayer.frame = bounds
        subLayer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: corner - 2).cgPath
        subLayer.shadowColor = UIColor.red.cgColor
        subLayer.shadowOpacity = 1
        subLayer.shadowRadius = 2

        subLayer.shadowOffset = CGSize(width: 3, height: 4)

        layer.insertSublayer(subLayer, at: 0)
    }

      /// Use this to set a gradient for the background.
      /// = This is a gradient with a shadow.
      func subGradientBackgroundShadow() {

          let corner: CGFloat = 15

          let subLayer = CALayer()
          subLayer.frame = bounds
          subLayer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: corner - 2).cgPath
          subLayer.shadowColor = UIColor.red.cgColor
          subLayer.shadowOpacity = 1
          subLayer.shadowRadius = 2

          subLayer.shadowOffset = CGSize(width: 3, height: 4)

          layer.insertSublayer(subLayer, at: 0)
      }


    /// LabelShadow
    /// - Parameter masksToBounds: Keep the layer in its bound
    /// - Exp.. Set to true to keep text in textview in its frame.
    /// - Exp.. Set to false to let shadow out side the frame.
    /// - Defalr corner radius is 7
    func labelTextfieldShadow() {
        let color = Color()

        let dark = color.labelBackgroundDark
        let borderColor = color.labelBorderColor

        layer.masksToBounds = false
        layer.borderWidth = 0.5
        layer.borderColor = borderColor
        layer.cornerRadius = 7
        self.backgroundColor = dark

        layer.shadowRadius = 7
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOffset = CGSize(width: 3, height: 3)
        layer.shadowOpacity = 0.6
    }



    /// Button gradient
    /// - Parameter cornerRadius: Set the radius of the button. Use outlet height / 2
    /// - Parameter shadowRadius: Set the shadow radius. 2
    func buttonGradientBackground(cornerRadius: CGFloat, shadowRadius: CGFloat) {
        let color = Color()

        let leading = color.buttonLeading
        let middle = color.buttonMiddle
        let trailing = color.buttonTrailing
        let borderColor = color.buttonBorderColor

        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = bounds
        gradientLayer.colors = [leading, middle, trailing]
        gradientLayer.locations = [0,0.3,1]
        gradientLayer.startPoint = CGPoint(x: 0.05, y: 0.5)
        gradientLayer.endPoint = CGPoint(x: 0.75, y: 0.5)
        gradientLayer.borderColor = borderColor
        gradientLayer.borderWidth = 1
        gradientLayer.cornerRadius = cornerRadius
        layer.insertSublayer(gradientLayer, at: 0)

        let subLayer = CALayer()
        subLayer.frame = bounds
        subLayer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius - 2).cgPath
        subLayer.shadowColor =  UIColor.black.cgColor
        subLayer.shadowOpacity = 1
        subLayer.shadowRadius = shadowRadius
        subLayer.shadowOffset = CGSize(width: 2, height: 3)
        layer.insertSublayer(subLayer, at: 0)
    }
}

Here is four screen shots of the screen.这是屏幕的四个屏幕截图。

在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明

This is a color struct to color all of the views.. Main view, Sub view, Labels and Buttons.这是一个用于为所有视图着色的颜色结构。主视图、子视图、标签和按钮。

struct Color {

    // Use these colors to style the main background.
    /// This color is used for the main view's background leading greadient color.
    let backgroundLeading = #colorLiteral(red: 0.2745098039, green: 0.231372549, blue: 0.231372549, alpha: 1).cgColor

    /// TThis color is used for the main view's background trailing greadient color.
    let backgroundTrailing = #colorLiteral(red: 0.2784313725, green: 0.2352941176, blue: 0.2352941176, alpha: 1).cgColor



    // Use these colors to style the sub view.
    /// This color is used for the sub view's leading greadient color.
    let subBackgroundLeading = #colorLiteral(red: 0.1960784314, green: 0.2549019608, blue: 0.2549019608, alpha: 1).cgColor

    /// This color is used for the sub view's trailing greadient color.
    let subBackgroundTrailing = #colorLiteral(red: 0.1012082246, green: 0.2111029723, blue: 0.1947238818, alpha: 1).cgColor

    /// This color is used for the sub view's border.
    let subBorderColor = #colorLiteral(red: 0.6000000238, green: 0.6000000238, blue: 0.6000000238, alpha: 1).cgColor



    // Use these colors to style the labels.
    /// This color is used for editing text background.
    let labelBackgroundLight = #colorLiteral(red: 0.921431005, green: 0.9214526415, blue: 0.9214410186, alpha: 1) as UIColor

    /// This color is used for disabled text background.
    let labelBackgroundDark = #colorLiteral(red: 0.1843137255, green: 0.137254902, blue: 0.1384684741, alpha: 1) as UIColor

    /// This color is used for the label's border.
    let labelBorderColor = #colorLiteral(red: 0.6, green: 0.6, blue: 0.6, alpha: 1).cgColor



    // Use these colors to style the buttons.
    /// This color is used for the button's leading greadient color.
    let buttonLeading = #colorLiteral(red: 0.1960784314, green: 0.2549019608, blue: 0.2549019608, alpha: 1).cgColor

    /// This color is used for the button's middle greadient color.
    let buttonMiddle = #colorLiteral(red: 0.2, green: 0.2, blue: 0.2, alpha: 1).cgColor

    /// This color is used for the button's trailing greadient color.
    let buttonTrailing = #colorLiteral(red: 0.1012082246, green: 0.2111029723, blue: 0.1947238818, alpha: 1).cgColor

    /// This color is used for the button's border color.
    let buttonBorderColor = #colorLiteral(red: 0.6000000238, green: 0.6000000238, blue: 0.6000000238, alpha: 1).cgColor


    // Use these colors for the text
    /// This color is used for the deiabled label and text field.
    let labelDisableColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)

    /// This color is used for the enabled label and text field.
    let labelEnableColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)

    /// The text color white.
    let labelWhiteTextColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)

    /// The text color Black
    let labelBlackTextColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
}

Instead of assuming that a layer is at a given index, just retain the laters you want to remove as an instance variable (or in an array of CALayers) and then tell the layer(s) to remove themselves from their super layer.与其假设某个图层位于给定的索引处,只需将要删除的后期元素保留为实例变量(或在 CALayer 数组中),然后告诉图层从它们的超级图层中删除自己

For example:例如:

var layersToRemoveLater = [CALayer]()
...
layersToRemoveLater.append(someLayer)
layersToRemoveLater.append(someOtherLayer)
...
layersToRemoveLater.forEach { $0.removeFromSuperLayer() }

The way to do this was to change each one of the extension to a class.这样做的方法是将每个扩展更改为一个类。 With extension you have to take care of all of the layout your self.通过扩展,您必须自己处理所有布局。 By using these as a class you can set each Button, Sub view Ect... in the storyboard, this way the view itself will redrawing the layout.通过将这些用作类,您可以在故事板中设置每个按钮、子视图等,这样视图本身将重新绘制布局。

/// Use this to set a greadient for the background.
/// = This is a greadient with no shadow.
class MainGradientView: UIView {

 override init(frame: CGRect) {
    super.init(frame: frame)
    setupView()
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    setupView()
}

private func setupView() {
    autoresizingMask = [.flexibleWidth, .flexibleHeight]

    guard let gradientLayer = self.layer as? CAGradientLayer else {
        return;
    }
    let color = Color()

    let leading = color.backgroundLeading
    let trailing = color.backgroundTrailing

    gradientLayer.frame = bounds
    gradientLayer.colors = [leading, trailing]
    gradientLayer.locations = [0,0.3]
    gradientLayer.startPoint = CGPoint(x: 0.05, y: 0.5)
    gradientLayer.endPoint = CGPoint(x: 0.75, y: 0.5)
}

override class var layerClass: AnyClass {
    return CAGradientLayer.self
}


}





/// Use this to set a greadient for the background.
/// = This is a greadient with a shadow.
class SubGradientView: UIView {

override init(frame: CGRect) {
    super.init(frame: frame)
    setupView()
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    setupView()
}

private func setupView() {
    autoresizingMask = [.flexibleWidth, .flexibleHeight]

    guard let gradientLayer = self.layer as? CAGradientLayer else {
        return;
    }

    let corner: CGFloat = 15
    let color = Color()

    let leading = color.subBackgroundLeading
    let trailing = color.subBackgroundTrailing
    let borderColor = color.subBorderColor

    gradientLayer.frame = self.bounds
    gradientLayer.colors = [leading, trailing]
    gradientLayer.locations = [0,0.3,1]
    gradientLayer.startPoint = CGPoint(x: 0.05, y: 0.5)
    gradientLayer.endPoint = CGPoint(x: 0.75, y: 0.5)
    gradientLayer.borderColor = borderColor
    gradientLayer.borderWidth = 0.4
    gradientLayer.cornerRadius = corner

    self.layer.shadowColor = UIColor.black.cgColor
    self.layer.shadowOpacity = 1
    self.layer.shadowRadius = 2
    self.layer.shadowOffset = CGSize(width: 3, height: 4)
}

override class var layerClass: AnyClass {
    return CAGradientLayer.self
}
}



/// Use this to set a greadient for the background.
/// = This is a greadient with no shadow.
class TabBarGradientView: UIView {

override init(frame: CGRect) {
    super.init(frame: frame)
    setupView()
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    setupView()
}

private func setupView() {
    autoresizingMask = [.flexibleWidth, .flexibleHeight]

    guard let gradientLayer = self.layer as? CAGradientLayer else {
        return;
    }


    let color = Color()

    let leading = color.buttonLeading
    let middle = color.buttonMiddle
    let trailing = color.buttonTrailing
    let borderColor = color.buttonBorderColor

    gradientLayer.frame = bounds
    gradientLayer.colors = [leading, middle, trailing]
    gradientLayer.locations = [0,0.3,1]
    gradientLayer.startPoint = CGPoint(x: 0.05, y: 0.5)
    gradientLayer.endPoint = CGPoint(x: 0.75, y: 0.5)
    gradientLayer.borderColor = borderColor
    gradientLayer.borderWidth = 1
    gradientLayer.cornerRadius = self.frame.width / 50
}

override class var layerClass: AnyClass {
    return CAGradientLayer.self
}
}


/// Use this to set a greadient for the background.
/// = This is a greadient with a shadow.
class ButtonGradientView: UIButton {

override init(frame: CGRect) {
    super.init(frame: frame)
    setupView()
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    setupView()
}

private func setupView() {
    autoresizingMask = [.flexibleWidth, .flexibleHeight]

    guard let gradientLayer = self.layer as? CAGradientLayer else {
        return;
    }


    let color = Color()

    let leading = color.buttonLeading
    let middle = color.buttonMiddle
    let trailing = color.buttonTrailing
    let borderColor = color.buttonBorderColor

    gradientLayer.frame = bounds
    gradientLayer.colors = [leading, middle, trailing]
    gradientLayer.locations = [0,0.3,1]
    gradientLayer.startPoint = CGPoint(x: 0.05, y: 0.5)
    gradientLayer.endPoint = CGPoint(x: 0.75, y: 0.5)
    gradientLayer.borderColor = borderColor
    gradientLayer.borderWidth = 1
    gradientLayer.cornerRadius = self.frame.height / 2

    self.layer.frame = bounds
    self.layer.shadowColor =  UIColor.black.cgColor
    self.layer.shadowOpacity = 1
    self.layer.shadowRadius = 2
    self.layer.shadowOffset = CGSize(width: 2, height: 3)
}

override class var layerClass: AnyClass {
    return CAGradientLayer.self
}
}


/// Use this to set a greadient for the keypad switch.
/// = This is a greadient with a shadow.
class SwitchGradientView: UIView {

override init(frame: CGRect) {
    super.init(frame: frame)
    setupView()
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    setupView()
}

private func setupView() {
    autoresizingMask = [.flexibleWidth, .flexibleHeight]

    guard let gradientLayer = self.layer as? CAGradientLayer else {
        return;
    }


    let color = Color()

    let leading = color.buttonLeading
    let middle = color.buttonMiddle
    let trailing = color.buttonTrailing
    let borderColor = color.buttonBorderColor

    gradientLayer.frame = bounds
    gradientLayer.colors = [leading, middle, trailing]
    gradientLayer.locations = [0,0.3,1]
    gradientLayer.startPoint = CGPoint(x: 0.05, y: 0.5)
    gradientLayer.endPoint = CGPoint(x: 0.75, y: 0.5)
    gradientLayer.borderColor = borderColor
    gradientLayer.borderWidth = 1
    gradientLayer.cornerRadius = 9

    self.layer.frame = bounds
    self.layer.shadowColor =  UIColor.black.cgColor
    self.layer.shadowOpacity = 1
    self.layer.shadowRadius = 2
    self.layer.shadowOffset = CGSize(width: 2, height: 3)
}

override class var layerClass: AnyClass {
    return CAGradientLayer.self
}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM