initial cut for the checkbox

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
Matt Bruce 2024-06-28 14:57:15 -05:00
parent eb78d507d6
commit 11a023d92a
5 changed files with 70 additions and 409 deletions

View File

@ -7,113 +7,44 @@
// //
import MVMCore import MVMCore
import VDS
/** /**
This class expects its height and width to be equal. This class expects its height and width to be equal.
*/ */
@objcMembers open class Checkbox: Control, MVMCoreUIViewConstrainingProtocol { @objcMembers open class Checkbox: VDS.Checkbox, VDSMoleculeViewProtocol, MVMCoreUIViewConstrainingProtocol {
//-------------------------------------------------- //------------------------------------------------------
// MARK: - Properties // MARK: - Properties
//-------------------------------------------------- //------------------------------------------------------
open var viewModel: CheckboxModel!
public var sizeObject: MFSizeObject? = MFSizeObject(standardSize: Checkbox.defaultHeightWidth, standardiPadPortraitSize: Checkbox.defaultHeightWidth + 6.0) open var delegateObject: MVMCoreUIDelegateObject?
open var additionalData: [AnyHashable : Any]?
// Form Validation // Form Validation
var fieldKey: String? var fieldKey: String?
var fieldValue: JSONValue? var fieldValue: JSONValue?
var groupName: String? var groupName: String?
var delegateObject: MVMCoreUIDelegateObject?
public var checkboxModel: CheckboxModel? { public var checkboxModel: CheckboxModel? {
model as? CheckboxModel viewModel
} }
public static let defaultHeightWidth: CGFloat = 18.0
/// If true the border of this checkbox will be circular.
public var isRound: Bool = false
/// Determined if the checkbox's UI should animated when selected.
public var isAnimated: Bool = true
/// Disables all selection logic when setting the value of isSelected, reducing it to a stored property. /// Disables all selection logic when setting the value of isSelected, reducing it to a stored property.
public var updateSelectionOnly: Bool = false public var updateSelectionOnly: Bool = false
/// The color of the background when checked.
public var checkedBackgroundColor: UIColor = .clear {
didSet {
if isSelected {
backgroundColor = checkedBackgroundColor
}
}
}
/// The color of the background when unChecked.
public var unCheckedBackgroundColor: UIColor = .clear {
didSet {
if !isSelected {
backgroundColor = unCheckedBackgroundColor
}
}
}
/// Retrieves ideeal radius value to curve square into a circle.
public var cornerRadiusValue: CGFloat {
bounds.size.height / 2
}
/// Action Block called when the switch is selected. /// Action Block called when the switch is selected.
public var actionBlock: ActionBlock? public var actionBlock: ActionBlock? {
get { nil }
/// Manages the appearance of the checkbox. set {
private var shapeLayer: CAShapeLayer? if let action = newValue {
onChange = { _ in
/// Width of the check mark. action()
public var checkWidth: CGFloat = 2 {
didSet {
if let shapeLayer = shapeLayer {
CATransaction.withDisabledAnimations {
shapeLayer.lineWidth = checkWidth
} }
}
}
}
open override var isEnabled: Bool {
didSet {
isUserInteractionEnabled = isEnabled
if isEnabled {
layer.borderColor = borderColor.cgColor
backgroundColor = isSelected ? checkedBackgroundColor : unCheckedBackgroundColor
setShapeLayerStrokeColor(checkColor)
} else { } else {
layer.borderColor = disabledBorderColor.cgColor onChange = nil
backgroundColor = disabledBackgroundColor
setShapeLayerStrokeColor(disabledCheckColor)
} }
} }
} }
public var disabledBackgroundColor: UIColor = .clear
public var disabledBorderColor: UIColor = .mvmCoolGray3
public var disabledCheckColor: UIColor = .mvmCoolGray3
/// Color of the check mark.
public var checkColor: UIColor = .mvmBlack {
didSet { setShapeLayerStrokeColor(checkColor) }
}
/// Border width of the checkbox
public var borderWidth: CGFloat = 1 {
didSet { layer.borderWidth = borderWidth }
}
/// border color of the Checkbox
public var borderColor: UIColor = .mvmBlack {
didSet { layer.borderColor = borderColor.cgColor }
}
/** /**
The represented state of the Checkbox. The represented state of the Checkbox.
@ -123,42 +54,18 @@ import MVMCore
override open var isSelected: Bool { override open var isSelected: Bool {
didSet { didSet {
if !updateSelectionOnly { if !updateSelectionOnly {
layoutIfNeeded() viewModel.selected = isSelected
(model as? CheckboxModel)?.selected = isSelected
shapeLayer?.removeAllAnimations()
updateCheckboxUI(isSelected: isSelected, isAnimated: isAnimated)
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate) _ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
updateAccessibilityLabel()
} }
} }
} }
//--------------------------------------------------
// MARK: - Constraints
//--------------------------------------------------
public var heightConstraint: NSLayoutConstraint?
public var widthConstraint: NSLayoutConstraint?
/// Updates the height and width anchors of the Checkbox with the assigned value.
public var heigthWidthConstant: CGFloat = Checkbox.defaultHeightWidth {
didSet {
heightConstraint?.constant = heigthWidthConstant
widthConstraint?.constant = heigthWidthConstant
}
}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Initializers // MARK: - Initializers
//-------------------------------------------------- //--------------------------------------------------
override public init(frame: CGRect) { override public init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
isAccessibilityElement = true
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "checkbox_action_hint")
accessibilityTraits = .button
updateAccessibilityLabel()
} }
/// There is currently no intention on using xib files. /// There is currently no intention on using xib files.
@ -167,122 +74,61 @@ import MVMCore
fatalError("xib file is not implemented for Checkbox.") fatalError("xib file is not implemented for Checkbox.")
} }
public convenience override init() { public convenience required init() {
self.init(frame:.zero) self.init(frame:.zero)
} }
public convenience init(isChecked: Bool) { public convenience init(isChecked: Bool) {
self.init(frame: .zero) self.init(frame: .zero)
checkAndBypassAnimations(selected: isChecked) isSelected = isChecked
} }
public convenience init(checkedBackgroundColor: UIColor, unCheckedBackgroundColor: UIColor, isChecked: Bool = false) { public convenience init(checkedBackgroundColor: UIColor, unCheckedBackgroundColor: UIColor, isChecked: Bool = false) {
self.init(frame: .zero) self.init(frame: .zero)
checkAndBypassAnimations(selected: isChecked) isSelected = isChecked
self.checkedBackgroundColor = checkedBackgroundColor
self.unCheckedBackgroundColor = unCheckedBackgroundColor
} }
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Lifecycle // MARK: - Lifecycle
//-------------------------------------------------- //--------------------------------------------------
override open func layoutSubviews() { open override func setup() {
super.layoutSubviews() super.setup()
bridge_accessibilityLabelBlock = { [weak self] in
// Attention: This needs to be addressed with the accessibility team.
// NOTE: Currently emptying description part of MVMCoreUICheckBox accessibility label to avoid crashing!
guard let self,
let state = MVMCoreUIUtility.hardcodedString(withKey: isSelected ? "checkbox_checked_state" : "checkbox_unchecked_state")
else { return nil }
return String(format: MVMCoreUIUtility.hardcodedString(withKey: "checkbox_desc_state") ?? "%@%@", "", state)
}
drawShapeLayer() bridge_accessibilityHintBlock = {
layer.cornerRadius = isRound ? cornerRadiusValue : 0 MVMCoreUIUtility.hardcodedString(withKey: "checkbox_action_hint")
} }
open override func setupView() {
super.setupView()
isUserInteractionEnabled = true
translatesAutoresizingMaskIntoConstraints = false
backgroundColor = .clear
widthConstraint = widthAnchor.constraint(equalToConstant: Checkbox.defaultHeightWidth)
heightConstraint = heightAnchor.constraint(equalToConstant: Checkbox.defaultHeightWidth)
heightWidthIsActive(true)
} }
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Actions // MARK: - Actions
//-------------------------------------------------- //--------------------------------------------------
open override func sendAction(_ action: Selector, to target: Any?, for event: UIEvent?) {
super.sendAction(action, to: target, for: event)
toggleAndAction()
}
open override func sendActions(for controlEvents: UIControl.Event) {
super.sendActions(for: controlEvents)
toggleAndAction()
}
/// This will toggle the state of the Checkbox and execute the actionBlock if provided. /// This will toggle the state of the Checkbox and execute the actionBlock if provided.
public func toggleAndAction() { public func toggleAndAction() {
isSelected.toggle() toggle()
actionBlock?()
} }
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Methods // MARK: - Methods
//-------------------------------------------------- //--------------------------------------------------
/// Creates the check mark layer.
private func drawShapeLayer() {
if shapeLayer == nil {
let shapeLayer = CAShapeLayer()
self.shapeLayer = shapeLayer
shapeLayer.frame = bounds
layer.addSublayer(shapeLayer)
shapeLayer.strokeColor = isEnabled ? checkColor.cgColor : disabledCheckColor.cgColor
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.path = checkMarkPath()
shapeLayer.lineJoin = .miter
shapeLayer.lineWidth = checkWidth
CATransaction.withDisabledAnimations {
shapeLayer.strokeEnd = isSelected ? 1 : 0
}
}
}
/// - returns: The CGPath of a UIBezierPath detailing the path of a checkmark
func checkMarkPath() -> CGPath {
let length = max(bounds.size.height, bounds.size.width)
let xInsetLeft = length * 0.25
let yInsetTop = length * 0.3
let innerWidth = length - (xInsetLeft + length * 0.25) // + Right X Inset
let innerHeight = length - (yInsetTop + length * 0.35) // + Bottom Y Inset
let startPoint = CGPoint(x: xInsetLeft, y: yInsetTop + (innerHeight / 2))
let pivotOffSet = CGPoint(x: xInsetLeft + (innerWidth * 0.33), y: yInsetTop + innerHeight)
let endOffset = CGPoint(x: xInsetLeft + innerWidth, y: yInsetTop)
let bezierPath = UIBezierPath()
bezierPath.move(to: startPoint)
bezierPath.addLine(to: pivotOffSet)
bezierPath.addLine(to: endOffset)
return bezierPath.cgPath
}
/// Programmatic means to check/uncheck the box. /// Programmatic means to check/uncheck the box.
/// - parameter selected: state of the check box: true = checked OR false = unchecked. /// - parameter selected: state of the check box: true = checked OR false = unchecked.
/// - parameter animated: allows the state of the checkbox to change with or without animation. /// - parameter animated: allows the state of the checkbox to change with or without animation.
public func updateSelection(to selected: Bool, animated: Bool) { public func updateSelection(to selected: Bool, animated: Bool) {
DispatchQueue.main.async { DispatchQueue.main.async {
self.isAnimated = animated
self.checkAndBypassAnimations(selected: selected) self.isSelected = selected
self.drawShapeLayer()
self.shapeLayer?.removeAllAnimations()
self.updateCheckboxUI(isSelected: selected, isAnimated: animated)
} }
} }
@ -291,154 +137,59 @@ import MVMCore
/// - parameter isAnimated: determines of the changes should animate or immediately refelect. /// - parameter isAnimated: determines of the changes should animate or immediately refelect.
public func updateCheckboxUI(isSelected: Bool, isAnimated: Bool) { public func updateCheckboxUI(isSelected: Bool, isAnimated: Bool) {
if isAnimated { DispatchQueue.main.async {
let animateStrokeEnd = CABasicAnimation(keyPath: "strokeEnd") self.isAnimated = isAnimated
animateStrokeEnd.timingFunction = CAMediaTimingFunction(name: .linear) self.isSelected = isSelected
animateStrokeEnd.duration = 0.3
animateStrokeEnd.fillMode = .both
animateStrokeEnd.isRemovedOnCompletion = false
animateStrokeEnd.fromValue = !isSelected ? 1 : 0
animateStrokeEnd.toValue = isSelected ? 1 : 0
self.shapeLayer?.add(animateStrokeEnd, forKey: "strokeEnd")
UIView.animate(withDuration: 0.2, delay: 0.1, options: .curveEaseOut, animations: {
self.backgroundColor = isSelected ? self.checkedBackgroundColor : self.unCheckedBackgroundColor
})
} else {
CATransaction.withDisabledAnimations {
self.shapeLayer?.strokeEnd = isSelected ? 1 : 0
}
backgroundColor = isSelected ? checkedBackgroundColor : unCheckedBackgroundColor
} }
} }
/// Adjust accessibility label based on state of Checkbox.
public func updateAccessibilityLabel() {
// Attention: This needs to be addressed with the accessibility team.
// NOTE: Currently emptying description part of MVMCoreUICheckBox accessibility label to avoid crashing!
if let state = MVMCoreUIUtility.hardcodedString(withKey: isSelected ? "checkbox_checked_state" : "checkbox_unchecked_state") {
accessibilityLabel = String(format: MVMCoreUIUtility.hardcodedString(withKey: "checkbox_desc_state") ?? "%@%@", "", state)
}
}
private func setShapeLayerStrokeColor(_ color: UIColor) {
if let shapeLayer = shapeLayer {
CATransaction.withDisabledAnimations {
shapeLayer.strokeColor = color.cgColor
}
}
}
public func heightWidthIsActive(_ isActive: Bool) {
heightConstraint?.isActive = isActive
widthConstraint?.isActive = isActive
}
private func checkAndBypassAnimations(selected: Bool) {
updateSelectionOnly = true
isSelected = selected
updateSelectionOnly = false
}
//--------------------------------------------------
// MARK: - UITouch
//--------------------------------------------------
open override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
sendActions(for: .touchUpInside)
}
override open func accessibilityActivate() -> Bool {
guard isEnabled else { return false }
sendActions(for: .touchUpInside)
return true
}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Molecular // MARK: - Molecular
//-------------------------------------------------- //--------------------------------------------------
open func needsToBeConstrained() -> Bool { true } open func needsToBeConstrained() -> Bool { true }
open override func reset() {
super.reset()
isEnabled = true public func horizontalAlignment() -> UIStackView.Alignment { .leading }
shapeLayer?.removeAllAnimations()
shapeLayer?.removeFromSuperlayer() public func updateView(_ size: CGFloat) {}
shapeLayer = nil
backgroundColor = .clear
borderColor = .mvmBlack
borderWidth = 1
checkColor = .mvmBlack
checkWidth = 2
checkAndBypassAnimations(selected: false)
}
public override func updateView(_ size: CGFloat) {
super.updateView(size)
if let dimension = sizeObject?.getValueBased(onSize: size) {
widthConstraint?.constant = dimension
heightConstraint?.constant = dimension
}
}
private func performCheckboxAction(with actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { private func performCheckboxAction(with actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
MVMCoreUIActionHandler.performActionUnstructured(with: actionModel, sourceModel: checkboxModel, additionalData: additionalData, delegateObject: delegateObject) MVMCoreUIActionHandler.performActionUnstructured(with: actionModel, sourceModel: checkboxModel, additionalData: additionalData, delegateObject: delegateObject)
} }
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData) public func viewModelDidUpdate() {
self.delegateObject = delegateObject FormValidator.setupValidation(for: viewModel, delegate: delegateObject?.formHolderDelegate)
guard let model = model as? CheckboxModel else { return } if let fieldKey = viewModel.fieldKey {
FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate)
if let fieldKey = model.fieldKey {
self.fieldKey = fieldKey self.fieldKey = fieldKey
} }
borderColor = (model.inverted ? model.invertedColor : model.borderColor).uiColor isAnimated = viewModel.animated
borderWidth = model.borderWidth if viewModel.selected {
updateSelectionOnly = true
checkColor = (model.inverted ? model.invertedColor : model.checkColor).uiColor isSelected = viewModel.selected
unCheckedBackgroundColor = (model.inverted ? model.invertedBackgroundColor : model.unCheckedBackgroundColor).uiColor updateSelectionOnly = false
checkedBackgroundColor = (model.inverted ? model.invertedBackgroundColor : model.checkedBackgroundColor).uiColor
disabledCheckColor = (model.inverted ? model.invertedColor : model.disabledCheckColor).uiColor
disabledBorderColor = (model.inverted ? model.invertedColor : model.disabledBorderColor).uiColor
disabledBackgroundColor = (model.inverted ? model.invertedColor : model.disabledBackgroundColor).uiColor
isAnimated = model.animated
isRound = model.round
if model.selected {
checkAndBypassAnimations(selected: model.selected)
} }
model.updateUI = { [weak self] in viewModel.updateUI = {
MVMCoreDispatchUtility.performBlock(onMainThread: { MVMCoreDispatchUtility.performBlock(onMainThread: { [weak self] in
guard let self = self else { return } guard let self = self else { return }
self.isEnabled = model.enabled isEnabled = viewModel.enabled
}) })
} }
isEnabled = model.enabled && !model.readOnly isEnabled = viewModel.enabled && !viewModel.readOnly
if (model.action != nil || model.offAction != nil) { if (viewModel.action != nil || viewModel.offAction != nil) {
actionBlock = { [weak self] in actionBlock = { [weak self] in
guard let self = self else { return } guard let self = self else { return }
if let offAction = model.offAction, !self.isSelected { if let offAction = viewModel.offAction, !isSelected {
self.performCheckboxAction(with: offAction, delegateObject: delegateObject, additionalData: additionalData) performCheckboxAction(with: offAction, delegateObject: delegateObject, additionalData: additionalData)
} else if let action = model.action { } else if let action = viewModel.action {
self.performCheckboxAction(with: action, delegateObject: delegateObject, additionalData: additionalData) performCheckboxAction(with: action, delegateObject: delegateObject, additionalData: additionalData)
} }
} }
} }

View File

@ -5,6 +5,7 @@
// Created by Chintakrinda, Arun Kumar (Arun) on 21/01/20. // Created by Chintakrinda, Arun Kumar (Arun) on 21/01/20.
// Copyright © 2020 Verizon Wireless. All rights reserved. // Copyright © 2020 Verizon Wireless. All rights reserved.
// //
import VDS
/// Protocol to apply to any model of a UI Control with a binary on/off nature. /// Protocol to apply to any model of a UI Control with a binary on/off nature.
/// ///
@ -28,20 +29,10 @@
public var readOnly: Bool = false public var readOnly: Bool = false
public var animated: Bool = true public var animated: Bool = true
public var inverted: Bool = false public var inverted: Bool = false
public var round: Bool = false
public var borderWidth: CGFloat = 1
public var borderColor: Color = Color(uiColor: .mvmBlack)
public var checkColor: Color = Color(uiColor: .mvmBlack)
public var unCheckedBackgroundColor: Color = Color(uiColor: .clear)
public var checkedBackgroundColor: Color = Color(uiColor: .clear)
public var disabledBackgroundColor: Color = Color(uiColor: .clear)
public var disabledBorderColor: Color = Color(uiColor: .mvmCoolGray3)
public var disabledCheckColor: Color = Color(uiColor: .mvmCoolGray3)
public var invertedColor: Color = Color(uiColor: .mvmWhite)
public var invertedBackgroundColor: Color = Color(uiColor: .mvmBlack)
public var action: ActionModelProtocol? public var action: ActionModelProtocol?
public var offAction: ActionModelProtocol? public var offAction: ActionModelProtocol?
public var surface: Surface { inverted ? .dark : .light }
public var fieldKey: String? public var fieldKey: String?
public var groupName: String = FormValidator.defaultGroupName public var groupName: String = FormValidator.defaultGroupName
public var baseValue: AnyHashable? public var baseValue: AnyHashable?
@ -60,17 +51,6 @@
case readOnly case readOnly
case inverted case inverted
case animated case animated
case round
case borderWidth
case borderColor
case checkColor
case invertedColor
case invertedBackgroundColor
case unCheckedBackgroundColor
case checkedBackgroundColor
case disabledBackgroundColor
case disabledCheckColor
case disabledBorderColor
case action case action
case fieldKey case fieldKey
case groupName case groupName
@ -113,46 +93,6 @@
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
if let borderWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .borderWidth) {
self.borderWidth = borderWidth
}
if let borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) {
self.borderColor = borderColor
}
if let checkColor = try typeContainer.decodeIfPresent(Color.self, forKey: .checkColor) {
self.checkColor = checkColor
}
if let unCheckedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .unCheckedBackgroundColor) {
self.unCheckedBackgroundColor = unCheckedBackgroundColor
}
if let checkedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .checkedBackgroundColor) {
self.checkedBackgroundColor = checkedBackgroundColor
}
if let disabledBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBackgroundColor) {
self.disabledBackgroundColor = disabledBackgroundColor
}
if let disabledBorderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBorderColor) {
self.disabledBorderColor = disabledBorderColor
}
if let disabledCheckColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledCheckColor) {
self.disabledCheckColor = disabledCheckColor
}
if let invertedColor = try typeContainer.decodeIfPresent(Color.self, forKey: .invertedColor) {
self.invertedColor = invertedColor
}
if let invertedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .invertedBackgroundColor) {
self.invertedBackgroundColor = invertedBackgroundColor
}
if let checked = try typeContainer.decodeIfPresent(Bool.self, forKey: .checked) { if let checked = try typeContainer.decodeIfPresent(Bool.self, forKey: .checked) {
self.selected = checked self.selected = checked
} }
@ -162,11 +102,7 @@
if let animated = try typeContainer.decodeIfPresent(Bool.self, forKey: .animated) { if let animated = try typeContainer.decodeIfPresent(Bool.self, forKey: .animated) {
self.animated = animated self.animated = animated
} }
if let round = try typeContainer.decodeIfPresent(Bool.self, forKey: .round) {
self.round = round
}
if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) { if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) {
self.inverted = inverted self.inverted = inverted
} }
@ -188,21 +124,10 @@
try container.encode(moleculeName, forKey: .moleculeName) try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(groupName, forKey: .groupName) try container.encodeIfPresent(groupName, forKey: .groupName)
try container.encodeIfPresent(fieldKey, forKey: .fieldKey) try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
try container.encodeIfPresent(borderColor, forKey: .borderColor)
try container.encode(borderWidth, forKey: .borderWidth)
try container.encode(selected, forKey: .checked) try container.encode(selected, forKey: .checked)
try container.encode(inverted, forKey: .inverted) try container.encode(inverted, forKey: .inverted)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier) try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encodeIfPresent(checkColor, forKey: .checkColor)
try container.encodeIfPresent(invertedColor, forKey: .invertedColor)
try container.encodeIfPresent(invertedBackgroundColor, forKey: .invertedBackgroundColor)
try container.encodeIfPresent(unCheckedBackgroundColor, forKey: .unCheckedBackgroundColor)
try container.encodeIfPresent(checkedBackgroundColor, forKey: .checkedBackgroundColor)
try container.encodeIfPresent(disabledBorderColor, forKey: .disabledBorderColor)
try container.encodeIfPresent(disabledBackgroundColor, forKey: .disabledBackgroundColor)
try container.encodeIfPresent(disabledCheckColor, forKey: .disabledCheckColor)
try container.encodeIfPresent(animated, forKey: .animated) try container.encodeIfPresent(animated, forKey: .animated)
try container.encodeIfPresent(round, forKey: .round)
try container.encode(enabled, forKey: .enabled) try container.encode(enabled, forKey: .enabled)
try container.encode(readOnly, forKey: .readOnly) try container.encode(readOnly, forKey: .readOnly)
try container.encodeModelIfPresent(action, forKey: .action) try container.encodeModelIfPresent(action, forKey: .action)

View File

@ -36,7 +36,7 @@
override open func setupView() { override open func setupView() {
super.setupView() super.setupView()
guard subviews.isEmpty else { return } guard subviews.isEmpty else { return }
addSubview(checkbox) addSubview(checkbox)
@ -66,9 +66,6 @@
alignCheckbox(.center) alignCheckbox(.center)
isAccessibilityElement = false isAccessibilityElement = false
accessibilityElements = [checkbox, label] accessibilityElements = [checkbox, label]
observation = observe(\.checkbox.isSelected, options: [.new]) { [weak self] _, _ in
self?.updateAccessibilityLabel()
}
} }
@objc override open func updateView(_ size: CGFloat) { @objc override open func updateView(_ size: CGFloat) {
@ -117,7 +114,6 @@
checkbox.set(with: checkBoxWithLabelModel.checkbox, delegateObject, additionalData) checkbox.set(with: checkBoxWithLabelModel.checkbox, delegateObject, additionalData)
label.set(with: checkBoxWithLabelModel.label, delegateObject, additionalData) label.set(with: checkBoxWithLabelModel.label, delegateObject, additionalData)
updateAccessibilityLabel()
} }
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
@ -135,11 +131,4 @@
override open func accessibilityActivate() -> Bool { override open func accessibilityActivate() -> Bool {
checkbox.accessibilityActivate() checkbox.accessibilityActivate()
} }
open func updateAccessibilityLabel() {
checkbox.updateAccessibilityLabel()
if let text = label.text {
checkbox.accessibilityLabel?.append(", \(text)")
}
}
} }

View File

@ -83,9 +83,7 @@
func updateAccessibilityLabel() { func updateAccessibilityLabel() {
var message = "" var message = ""
checkbox.updateAccessibilityLabel()
if let checkboxLabel = checkbox.accessibilityLabel, !checkboxLabel.isEmpty { if let checkboxLabel = checkbox.accessibilityLabel, !checkboxLabel.isEmpty {
message += checkboxLabel + ", " message += checkboxLabel + ", "
} }

View File

@ -88,9 +88,7 @@
func updateAccessibilityLabel() { func updateAccessibilityLabel() {
var message = "" var message = ""
checkbox.updateAccessibilityLabel()
if let checkboxLabel = checkbox.accessibilityLabel { if let checkboxLabel = checkbox.accessibilityLabel {
message += checkboxLabel + ", " message += checkboxLabel + ", "
} }