Загрузите CAShapeLayer с UIButton в методе viewWillAppear - PullRequest
0 голосов
/ 14 мая 2018

У меня есть пользовательская кнопка с некоторым эффектом тени, после класса, которую я использую, чтобы создать пользовательскую кнопку, которую я получил от stackoverflow. Это использует CAShapeLayer, чтобы дать эффект тени на кнопку.

import UIKit

class CustomButton: UIButton {

var shadowLayer: CAShapeLayer!
override func layoutSubviews() {
    super.layoutSubviews()

    if shadowLayer == nil {
        shadowLayer = CAShapeLayer()
        shadowLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: 12).cgPath

        shadowLayer.fillColor = UIColor.white.cgColor
        shadowLayer.shadowColor = UIColor.darkGray.cgColor
        shadowLayer.shadowPath = shadowLayer.path
        shadowLayer.shadowOffset = CGSize(width: 2.0, height: 2.0)
        shadowLayer.shadowOpacity = 0.8
        shadowLayer.shadowRadius = 2

        layer.insertSublayer(shadowLayer, at: 0)
        //layer.insertSublayer(shadowLayer, below: nil) // also works
    }
}
}

Ниже приведено изображение экрана, на котором я создал 4 кнопки, используя этот класс CustomButton, который отлично работает.

enter image description here

когда нажата любая кнопка из четырех выше, я изменил ее следующее свойство, чтобы оно могло выглядеть как активная кнопка.

// to make button active
    func setSelectedButton(sender:CustomButton){
        //sender.backgroundColor = UIColor.red
        sender.shadowLayer.fillColor = UIColor(named: "headerColor")?.cgColor
        sender.setTitleColor(UIColor.white, for: .normal)
    }
// to make button inactive 
    func setUnselected(sender:CustomButton){
        //sender.backgroundColor = UIColor.init(red: 80/255, green:101/255, blue: 161/255, alpha: 1)
        sender.shadowLayer.fillColor = UIColor.white.cgColor
        sender.setTitleColor(.black, for: .normal)
    }

Все отлично работает. Теперь я хочу, чтобы всякий раз, когда появлялось представление, я хочу, чтобы первая кнопка была выбрана по умолчанию, а для этого используется рутина рутина, что я написал следующий код в viewWillAppearMethod

override func viewWillAppear(_ animated: Bool) {
        self.navigationItem.title = navigationTitle
        self.view.makeToastActivity(.center)
        self.routineButton.sendActions(for: .touchUpInside) //default selection of routineButton
        loadEvaluationList(userId: 8, evaluationType: "RT") {
            self.view.hideToastActivity()
        }
    }

когда self.routineButton.sendActions(for: .touchUpInside) выполняет его, вызывается метод setSelectedButton(sender:CustomButton), который выдает ошибку в следующей строке

 sender.shadowLayer.fillColor = UIColor(named: "headerColor")?.cgColor

, который говорит, что shadowLayer - ноль. Эта проблема возникает, только когда я пытаюсь установить выбранную по умолчанию кнопку в методе viewWillAppear, в противном случае он работает идеально. Я думаю, что проблема возникает, потому что свойство shadowLayer CustomButton не инициализируется во время viewWillAppear. так кто-нибудь знает, что мне делать? это будет полезно. Заранее спасибо.

1 Ответ

0 голосов
/ 14 мая 2018

Переместите код инициализации для shadowLayer в методы init, что-то вроде этого:

import UIKit

class CustomButton: UIButton {

    var shadowLayer: CAShapeLayer!

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.initShadowLayer()
    }

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

    func initShadowLayer() {
        if shadowLayer == nil {
            shadowLayer = CAShapeLayer()
            shadowLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: 12).cgPath

            shadowLayer.fillColor = UIColor.white.cgColor
            shadowLayer.shadowColor = UIColor.darkGray.cgColor
            shadowLayer.shadowPath = shadowLayer.path
            shadowLayer.shadowOffset = CGSize(width: 2.0, height: 2.0)
            shadowLayer.shadowOpacity = 0.8
            shadowLayer.shadowRadius = 2

            layer.insertSublayer(shadowLayer, at: 0)
        }

    }

    override func layoutSubviews() {
        super.layoutSubviews()

        // Reset the path because bounds could have been changed
        shadowLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: 12).cgPath
        shadowLayer.shadowPath = shadowLayer.path
    }
}

viewWillAppear вызывается до layoutSubviews кнопки, а shadowLayer еще не инициализировано.Также старайтесь не вызывать sendActions(for: .touchUpInside), вместо этого вызывайте функцию setSelectedButton, если вы просто хотите настроить внешний вид кнопки.

...