-1

I need that clickable button like picture ( there are 4 buttons show fill and empty state ). It is a specific ui component or I have to make it myself with a kind of custom rounded button or something else ? I need to use toogle option ?

enter image description here

roadRunner
  • 173
  • 1
  • 23
  • 1
    It's a Radio Button, and there isn't something already done in Swift. What's most look alike (as the behavior), is the "check" the the left in the tableView. In native apps: `Settings.app/WiFi/Confirm access`, you can select none, notify, ask. – Larme Nov 12 '20 at 15:55
  • @Larme thanks, Radio button opened my way and there are similar questions here – roadRunner Nov 12 '20 at 16:25

1 Answers1

1

i have already done one with the native tools of UIKit.

here is the code:

    import UIKit
    import Foundation
    @IBDesignable
    public class CustomRadioButton: UIButton {
    
    internal var outerCircleLayer = CAShapeLayer()
    internal var innerCircleLayer = CAShapeLayer()
    
    
    @IBInspectable public var outerCircleColor: UIColor = UIColor.yellow {
        didSet {
            outerCircleLayer.strokeColor = outerCircleColor.cgColor
        }
    }
    public var innerCircleCircleColor: UIColor = UIColor.black {
        didSet {
            setFillState()
        }
    }
    
    public var outerCircleLineWidth: CGFloat = 3.0
        
    public var innerCircleGap: CGFloat = 0.0
    
    override public init(frame: CGRect) {
        super.init(frame: frame)
        customInitialization()
    }
    // MARK: Initialization
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        customInitialization()
    }
   internal var setCircleRadius: CGFloat {
        let width = bounds.width
        let height = bounds.height
        
        let length = width > height ? height : width
        return (length - outerCircleLineWidth) / 2
    }
    


private var setCircleFrame: CGRect {
        let width = bounds.width
        let height = bounds.height
        
        let radius = setCircleRadius
        let x: CGFloat
        let y: CGFloat
        
        if width > height {
            y = outerCircleLineWidth / 2
            x = (width / 2) - radius
        } else {
            x = outerCircleLineWidth / 2
            y = (height / 2) - radius
        }
        
        let diameter = 2 * radius
        return CGRect(x: x, y: y, width: diameter, height: diameter)
    }
    
    private var circlePath: UIBezierPath {
        return UIBezierPath(roundedRect: setCircleFrame, cornerRadius: setCircleRadius)
    }
    
    private var fillCirclePath: UIBezierPath {
        let trueGap = innerCircleGap + (outerCircleLineWidth / 2)
        return UIBezierPath(roundedRect: setCircleFrame.insetBy(dx: trueGap, dy: trueGap), cornerRadius: setCircleRadius)
        
    }
    
    private func customInitialization() {
        outerCircleLayer.frame = bounds
        outerCircleLayer.lineWidth = outerCircleLineWidth
        outerCircleLayer.fillColor = UIColor.clear.cgColor
        outerCircleLayer.strokeColor = outerCircleColor.cgColor
        layer.addSublayer(outerCircleLayer)
        
        innerCircleLayer.frame = bounds
        innerCircleLayer.lineWidth = outerCircleLineWidth
        innerCircleLayer.fillColor = UIColor.clear.cgColor
        innerCircleLayer.strokeColor = UIColor.clear.cgColor
        layer.addSublayer(innerCircleLayer)
        
        setFillState()
    }
    
    private func setCircleLayouts() {
        outerCircleLayer.frame = bounds
        outerCircleLayer.lineWidth = outerCircleLineWidth
        outerCircleLayer.path = circlePath.cgPath
        
        innerCircleLayer.frame = bounds
        innerCircleLayer.lineWidth = outerCircleLineWidth
        innerCircleLayer.path = fillCirclePath.cgPath
    }
    
    // MARK: Custom
    private func setFillState() {
        if self.isSelected {
            innerCircleLayer.fillColor = UIColor.blue.cgColor
        } else {
            innerCircleLayer.fillColor = outerCircleColor.cgColor
        }
    }
// Overriden methods.
    override public func prepareForInterfaceBuilder() {
        customInitialization()
    }
    override public func layoutSubviews() {
        super.layoutSubviews()
        setCircleLayouts()
    }
    override public var isSelected: Bool {
        didSet {
            setFillState()
        }
    }
    
}
kuryga
  • 61
  • 3