Peter Lapisu
Peter Lapisu

Reputation: 20965

UIButton System style selected state, keep image and background

When using the System style of UIButton (nope, i don't want to use the Custom style, as the system provides animations, etc...)

The selected state of system button adds a background and removes the image

enter image description here

This is the Default state

enter image description here

And i want to achieve a selected style like this, where the look when selected is the same as the custom button

enter image description here

Upvotes: 1

Views: 452

Answers (2)

Karthik
Karthik

Reputation: 77

Add this class and set it to your button class

class KButton: UIButton {

var view: UIButton!

@IBInspectable public var textPadding: CGFloat = 5.0 {
    didSet {
        layoutSubviews()
    }
}

@IBInspectable public var circleRadius: CGFloat = 10 {
    didSet {
        layoutSubviews()
    }
}

@IBInspectable public var circleWidth: CGFloat = 2.0 {
    didSet {
        layoutSubviews()
    }
}

@IBInspectable public var currentState: Bool = false {
    didSet {
        layoutSubviews()
    }
}

override func layoutSubviews() {
    super.layoutSubviews()
    if view != nil {
        view?.removeFromSuperview()
    }
    view = UIButton(frame: CGRect(x: -(self.frame.height) - textPadding, y: 0, width: self.frame.height, height: self.frame.height))
    view.backgroundColor = UIColor.clear

    let circlePath = UIBezierPath(arcCenter: CGPoint(x: view.frame.height/2, y: view.frame.height/2), radius: circleRadius, startAngle: 0, endAngle: CGFloat(Double.pi * 2), clockwise: true)
    let shapeLayer = CAShapeLayer()
    shapeLayer.path = circlePath.cgPath
    shapeLayer.fillColor = UIColor.clear.cgColor
    shapeLayer.strokeColor = self.tintColor.cgColor
    shapeLayer.lineWidth = circleWidth
    view.layer.addSublayer(shapeLayer)

    if currentState {
        let circlePath1 = UIBezierPath(arcCenter: CGPoint(x: view.frame.height/2, y: view.frame.height/2), radius: (circleRadius - (circleWidth * 2)), startAngle: 0, endAngle: CGFloat(Double.pi * 2), clockwise: true)
        let shapeLayer1 = CAShapeLayer()
        shapeLayer1.path = circlePath1.cgPath
        shapeLayer1.fillColor = self.tintColor.cgColor
        shapeLayer1.strokeColor = self.tintColor.cgColor
        shapeLayer1.lineWidth = circleWidth
        view.layer.addSublayer(shapeLayer1)
    }

    self.addSubview(view)
 }
}

Then in you click action

@IBAction func buttonClicked(_ sender: KButton) {
    sender.currentState = !sender.currentState
}

Make sure to choose the type as KButton

Upvotes: 0

Peter Lapisu
Peter Lapisu

Reputation: 20965

ok, finally manged that one out, the key was not to allow the switch to selected state

class ControlButton: UIButton {

    var sImage: UIImage?
    var dImage: UIImage?

    override func awakeFromNib() {
        super.awakeFromNib()

        sImage = image(for: .selected)
        dImage = image(for: .normal)

    }

    override open var isSelected: Bool {

        set {
            if newValue {
                setImage(sImage, for: .normal)
            } else {
                setImage(dImage, for: .normal)
            }
        }
        get {
            return false
        }

    }

}

Upvotes: 1

Related Questions