UIB кнопка со значением углаRadius, тенью и фоном для состояния - PullRequest
0 голосов
/ 26 февраля 2020

Это сложная проблема, решение которой я не могу найти.

Мне нужно UIButton с:

  1. закругленными углами,
  2. фоном цвет для состояния,
  3. тень.

Я могу получить угловой радиус и цвет фона для состояния, создающего подклассы a UIButton и задав параметры:

// The button is set to "type: Custom" in the interface builder.

// 1. rounded corners
self.layer.cornerRadius = 10.0

// 2. Color for state
self.backgroundColor = UIColor.orange // for state .normal
self.setBackgroundColor(color: UIColor.red, forState: .highlighted)

// 3. Add the shadow
self.layer.shadowColor = UIColor.black.cgColor
self.layer.shadowOffset = CGSize(width: 0, height: 3)
self.layer.shadowOpacity = 0.3
self.layer.shadowRadius = 6.0
self.layer.masksToBounds = false


// I'm also using an extension to be able to set the background color
extension UIButton {
    func setBackgroundColor(color: UIColor, forState: UIControl.State) {        
        UIGraphicsBeginImageContext(CGSize(width: 1, height: 1))
        if let context = UIGraphicsGetCurrentContext() {
            context.setFillColor(color.cgColor)
            context.fill(CGRect(x: 0, y: 0, width: 1, height: 1))
            let colorImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            self.setBackgroundImage(colorImage, for: forState)
        }
    }
}

Проблема:
Как только кнопка отрисована, она выглядит хорошо, имеет желаемый цвет фона, закругленные углы и тень. Но после нажатия setBackgroundImage(image, for: forState) запускается и избавляется от радиуса , поэтому кнопка отображается в виде квадрата с нужным цветом и тенью.

Is есть способ сохранить радиус при нажатии кнопки (.highlighted)?

Я пробовал решения из этого поста (например), но никто не рассматривал setBackgroundImage(image, for: forState). Я не могу найти ничего, что работает ...

1 Ответ

1 голос
/ 27 февраля 2020

Если вы просто хотите изменить цвет фона для .normal и .highlighted - то есть вам не нужно фоновое изображение - вы можете переопределить var isHighlighted для обработки изменений цвета.

Вот пример UIButton подкласс. Он помечен @IBDesignable и имеет цвета normalBackground и highlightBackground, помеченные как @IBInspectable, так что вы можете установить их в Раскадровке / Интерфейсном Разработчике:

@IBDesignable
class HighlightButton: UIButton {

    @IBInspectable
    var normalBackground: UIColor = .clear {
        didSet {
            backgroundColor = self.normalBackground
        }
    }

    @IBInspectable
    var highlightBackground: UIColor = .clear

    override open var isHighlighted: Bool {
        didSet {
            backgroundColor = isHighlighted ? highlightBackground : normalBackground
        }
    }

    func setBackgroundColor(_ c: UIColor, forState: UIControl.State) -> Void {
        if forState == UIControl.State.normal {
            normalBackground = c
        } else if forState == UIControl.State.highlighted {
            highlightBackground = c
        } else {
            // implement other states as desired
        }
    }

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

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

    func commonInit() -> Void {

        // 1. rounded corners
        self.layer.cornerRadius = 10.0

        // 2. Default Colors for state
        self.setBackgroundColor(.orange, forState: .normal)
        self.setBackgroundColor(.red, forState: .highlighted)

        // 3. Add the shadow
        self.layer.shadowColor = UIColor.black.cgColor
        self.layer.shadowOffset = CGSize(width: 0, height: 3)
        self.layer.shadowOpacity = 0.3
        self.layer.shadowRadius = 6.0
        self.layer.masksToBounds = false

    }

}
...