Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/96.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 透明渐变在UIView类中不起作用_Ios_Swift_Uiview - Fatal编程技术网

Ios 透明渐变在UIView类中不起作用

Ios 透明渐变在UIView类中不起作用,ios,swift,uiview,Ios,Swift,Uiview,我试图在UIView类中为UIView添加一个透明渐变,但它不起作用 class RecipesDetailsView: UIView { override init(frame: CGRect) { super.init(frame: frame) layoutUI() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been im

我试图在
UIView
类中为
UIView
添加一个透明渐变,但它不起作用

class RecipesDetailsView: UIView {

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

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

    lazy var containerView: UIView = {
        let containerView = UIView()
        containerView.backgroundColor = .white
        let gradientMaskLayer = CAGradientLayer()
        gradientMaskLayer.frame = containerView.bounds
        gradientMaskLayer.colors = [UIColor.clear.cgColor, UIColor.white.cgColor]
        gradientMaskLayer.locations = [0, 1]
        containerView.layer.mask = gradientMaskLayer
        containerView.fadeView(style: .bottom, percentage: 0.5)
        containerView.translatesAutoresizingMaskIntoConstraints = false
        return containerView
    }()

    lazy var startCookingButton: UIButton = {
        let startCookingButton = UIButton(type: .system)
        startCookingButton.setTitle("Start cooking", for: .normal)
        startCookingButton.setTitleColor(.white, for: .normal)
        startCookingButton.backgroundColor = .CustomGreen()
        startCookingButton.layer.cornerRadius = 8.0
        startCookingButton.translatesAutoresizingMaskIntoConstraints = false
        startCookingButton.titleLabel?.font = UIFont(name: "AvenirNext-Bold", size: 14)
        return startCookingButton
    }()

    lazy var saveButton: UIButton = {
        let saveButton = UIButton(type: .system)
        saveButton.setTitleColor(.customDarkGray(), for: .normal)
        saveButton.setTitle("Save", for: .normal)
        saveButton.setImage(UIImage(systemName: "heart"), for: .normal)
        saveButton.imageEdgeInsets = UIEdgeInsets(top: 0,left: -5,bottom: 0,right: 0)
        saveButton.titleEdgeInsets = UIEdgeInsets(top: 0,left: 0,bottom: 0,right: -5)
        saveButton.titleLabel?.font = UIFont(name: "AvenirNext-Bold", size: 14)
        saveButton.tintColor = .customDarkGray()
        saveButton.backgroundColor = .clear
        saveButton.translatesAutoresizingMaskIntoConstraints = false
        return saveButton
    }()

    func setupContainerViewConstraints() {
        NSLayoutConstraint.activate([
            containerView.bottomAnchor.constraint(equalTo: bottomAnchor),
            containerView.leadingAnchor.constraint(equalTo: leadingAnchor),
            containerView.trailingAnchor.constraint(equalTo: trailingAnchor),
            containerView.heightAnchor.constraint(equalToConstant: frame.width / 5)
        ])
    }

    func setupStartCookingButton() {
        NSLayoutConstraint.activate([
            startCookingButton.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16),
            startCookingButton.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -32),
            startCookingButton.heightAnchor.constraint(equalToConstant: 55),
            startCookingButton.widthAnchor.constraint(equalToConstant: frame.width * (2.5/4))
        ])
    }

    func setupSaveButtonConstraints() {
        NSLayoutConstraint.activate([
            saveButton.centerYAnchor.constraint(equalTo: startCookingButton.centerYAnchor),
            saveButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
            saveButton.heightAnchor.constraint(equalTo: startCookingButton.heightAnchor),
            saveButton.widthAnchor.constraint(equalToConstant: frame.width * (1.2/4))
        ])
    }

    func addSubviews() {
        addSubview(containerView)
        containerView.addSubview(startCookingButton)
        containerView.addSubview(saveButton)
    }

    func layoutUI() {
        addSubviews()
        setupContainerViewConstraints()
        setupStartCookingButton()
        setupSaveButtonConstraints()
    }
}
我想要的是:

我从代码中获得的信息:

图层不会随视图“自动调整大小”,因此您需要保留渐变图层作为属性,并在视图布局更改时更新其边框

添加此属性:

private var gradientMaskLayer: CAGradientLayer!
然后,在
lazy var containerView:UIView=
change中:

let gradientMaskLayer = CAGradientLayer()
致:

然后,添加此函数:

override func layoutSubviews() {
    super.layoutSubviews()
    gradientMaskLayer.frame = bounds
}

编辑

但是,这会将渐变遮罩应用于
containerView
及其子视图(按钮),这可能不是您想要的

因此,将
addsubview()
func更改为:

func addSubviews() {
    addSubview(containerView)

    // add buttons to self, not to containerView
    //containerView.addSubview(startCookingButton)
    //containerView.addSubview(saveButton)
    addSubview(startCookingButton)
    addSubview(saveButton)

}

编辑2

下面是一个完整的实现,视图控制器的背景设置为红色:

class TestViewController: UIViewController {

    var rv: RecipesDetailsView!

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .red
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        // with the way you are setting up the layout,
        // we need to add the view here where we know the
        // frame has been setup
        if rv == nil {
            let w = view.frame.width
            let h = w / 5.0 * 2.0
            let t = view.frame.height - h
            rv = RecipesDetailsView(frame: CGRect(x: 0.0, y: t, width: w, height: h))
            view.addSubview(rv)
        }
    }

}

class RecipesDetailsView: UIView {

    // add this var / property
    private var gradientMaskLayer: CAGradientLayer!

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

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

    override func layoutSubviews() {
        super.layoutSubviews()
        // layers do not follow frame changes, so update here
        gradientMaskLayer.frame = bounds
    }

    lazy var containerView: UIView = {
        let containerView = UIView()
        containerView.backgroundColor = .white
        gradientMaskLayer = CAGradientLayer()
        gradientMaskLayer.frame = containerView.bounds
        gradientMaskLayer.colors = [UIColor.clear.cgColor, UIColor.white.cgColor]
        gradientMaskLayer.locations = [0, 1]
        containerView.layer.mask = gradientMaskLayer
        //containerView.fadeView(style: .bottom, percentage: 0.5)
        containerView.translatesAutoresizingMaskIntoConstraints = false
        return containerView
    }()

    lazy var startCookingButton: UIButton = {
        let startCookingButton = UIButton(type: .system)
        startCookingButton.setTitle("Start cooking", for: .normal)
        startCookingButton.setTitleColor(.white, for: .normal)
        //startCookingButton.backgroundColor = .CustomGreen()
        startCookingButton.backgroundColor = .systemGreen
        startCookingButton.layer.cornerRadius = 8.0
        startCookingButton.translatesAutoresizingMaskIntoConstraints = false
        startCookingButton.titleLabel?.font = UIFont(name: "AvenirNext-Bold", size: 14)
        return startCookingButton
    }()

    lazy var saveButton: UIButton = {
        let saveButton = UIButton(type: .system)
        //saveButton.setTitleColor(.customDarkGray(), for: .normal)
        saveButton.setTitleColor(.darkGray, for: .normal)
        saveButton.setTitle("Save", for: .normal)
        saveButton.setImage(UIImage(systemName: "heart"), for: .normal)
        saveButton.imageEdgeInsets = UIEdgeInsets(top: 0,left: -5,bottom: 0,right: 0)
        saveButton.titleEdgeInsets = UIEdgeInsets(top: 0,left: 0,bottom: 0,right: -5)
        saveButton.titleLabel?.font = UIFont(name: "AvenirNext-Bold", size: 14)
        //saveButton.tintColor = .customDarkGray()
        saveButton.tintColor = .darkGray
        saveButton.backgroundColor = .clear
        saveButton.translatesAutoresizingMaskIntoConstraints = false
        return saveButton
    }()

    func setupContainerViewConstraints() {
        NSLayoutConstraint.activate([
            containerView.bottomAnchor.constraint(equalTo: bottomAnchor),
            containerView.leadingAnchor.constraint(equalTo: leadingAnchor),
            containerView.trailingAnchor.constraint(equalTo: trailingAnchor),
            containerView.heightAnchor.constraint(equalToConstant: frame.width / 5)
        ])
    }

    func setupStartCookingButton() {
        NSLayoutConstraint.activate([
            startCookingButton.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16),
            startCookingButton.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -32),
            startCookingButton.heightAnchor.constraint(equalToConstant: 55),
            startCookingButton.widthAnchor.constraint(equalToConstant: frame.width * (2.5/4))
        ])
    }

    func setupSaveButtonConstraints() {
        NSLayoutConstraint.activate([
            saveButton.centerYAnchor.constraint(equalTo: startCookingButton.centerYAnchor),
            saveButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
            saveButton.heightAnchor.constraint(equalTo: startCookingButton.heightAnchor),
            saveButton.widthAnchor.constraint(equalToConstant: frame.width * (1.2/4))
        ])
    }

    func addSubviews() {
        addSubview(containerView)

        // add buttons to self, not to containerView
        //containerView.addSubview(startCookingButton)
        //containerView.addSubview(saveButton)
        addSubview(startCookingButton)
        addSubview(saveButton)

    }

    func layoutUI() {
        addSubviews()
        setupContainerViewConstraints()
        setupStartCookingButton()
        setupSaveButtonConstraints()
    }
}
结果:


我认为由于您使用的是自动布局,containerView.bounds为零。尝试添加一个框架来查看。@Joshua我尝试过,它会使按钮消失。你能添加你得到的和你想要得到的图像吗?@ValentinaKonatar我添加了我从代码中得到的和我想要得到的图像make@AhmedAbdElaziz-什么是
.fadeView(样式:。底部,百分比:0.5)
?编辑您的问题并包括您的
.fadeView
扩展名。我评论
fadeView
扩展名
class TestViewController: UIViewController {

    var rv: RecipesDetailsView!

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .red
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        // with the way you are setting up the layout,
        // we need to add the view here where we know the
        // frame has been setup
        if rv == nil {
            let w = view.frame.width
            let h = w / 5.0 * 2.0
            let t = view.frame.height - h
            rv = RecipesDetailsView(frame: CGRect(x: 0.0, y: t, width: w, height: h))
            view.addSubview(rv)
        }
    }

}

class RecipesDetailsView: UIView {

    // add this var / property
    private var gradientMaskLayer: CAGradientLayer!

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

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

    override func layoutSubviews() {
        super.layoutSubviews()
        // layers do not follow frame changes, so update here
        gradientMaskLayer.frame = bounds
    }

    lazy var containerView: UIView = {
        let containerView = UIView()
        containerView.backgroundColor = .white
        gradientMaskLayer = CAGradientLayer()
        gradientMaskLayer.frame = containerView.bounds
        gradientMaskLayer.colors = [UIColor.clear.cgColor, UIColor.white.cgColor]
        gradientMaskLayer.locations = [0, 1]
        containerView.layer.mask = gradientMaskLayer
        //containerView.fadeView(style: .bottom, percentage: 0.5)
        containerView.translatesAutoresizingMaskIntoConstraints = false
        return containerView
    }()

    lazy var startCookingButton: UIButton = {
        let startCookingButton = UIButton(type: .system)
        startCookingButton.setTitle("Start cooking", for: .normal)
        startCookingButton.setTitleColor(.white, for: .normal)
        //startCookingButton.backgroundColor = .CustomGreen()
        startCookingButton.backgroundColor = .systemGreen
        startCookingButton.layer.cornerRadius = 8.0
        startCookingButton.translatesAutoresizingMaskIntoConstraints = false
        startCookingButton.titleLabel?.font = UIFont(name: "AvenirNext-Bold", size: 14)
        return startCookingButton
    }()

    lazy var saveButton: UIButton = {
        let saveButton = UIButton(type: .system)
        //saveButton.setTitleColor(.customDarkGray(), for: .normal)
        saveButton.setTitleColor(.darkGray, for: .normal)
        saveButton.setTitle("Save", for: .normal)
        saveButton.setImage(UIImage(systemName: "heart"), for: .normal)
        saveButton.imageEdgeInsets = UIEdgeInsets(top: 0,left: -5,bottom: 0,right: 0)
        saveButton.titleEdgeInsets = UIEdgeInsets(top: 0,left: 0,bottom: 0,right: -5)
        saveButton.titleLabel?.font = UIFont(name: "AvenirNext-Bold", size: 14)
        //saveButton.tintColor = .customDarkGray()
        saveButton.tintColor = .darkGray
        saveButton.backgroundColor = .clear
        saveButton.translatesAutoresizingMaskIntoConstraints = false
        return saveButton
    }()

    func setupContainerViewConstraints() {
        NSLayoutConstraint.activate([
            containerView.bottomAnchor.constraint(equalTo: bottomAnchor),
            containerView.leadingAnchor.constraint(equalTo: leadingAnchor),
            containerView.trailingAnchor.constraint(equalTo: trailingAnchor),
            containerView.heightAnchor.constraint(equalToConstant: frame.width / 5)
        ])
    }

    func setupStartCookingButton() {
        NSLayoutConstraint.activate([
            startCookingButton.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16),
            startCookingButton.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -32),
            startCookingButton.heightAnchor.constraint(equalToConstant: 55),
            startCookingButton.widthAnchor.constraint(equalToConstant: frame.width * (2.5/4))
        ])
    }

    func setupSaveButtonConstraints() {
        NSLayoutConstraint.activate([
            saveButton.centerYAnchor.constraint(equalTo: startCookingButton.centerYAnchor),
            saveButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
            saveButton.heightAnchor.constraint(equalTo: startCookingButton.heightAnchor),
            saveButton.widthAnchor.constraint(equalToConstant: frame.width * (1.2/4))
        ])
    }

    func addSubviews() {
        addSubview(containerView)

        // add buttons to self, not to containerView
        //containerView.addSubview(startCookingButton)
        //containerView.addSubview(saveButton)
        addSubview(startCookingButton)
        addSubview(saveButton)

    }

    func layoutUI() {
        addSubviews()
        setupContainerViewConstraints()
        setupStartCookingButton()
        setupSaveButtonConstraints()
    }
}