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 ?
Asked
Active
Viewed 55 times
-1
-
1It'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 Answers
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