diff --git a/MVMCoreUI/Atomic/Atoms/Views/Checkbox.swift b/MVMCoreUI/Atomic/Atoms/Views/Checkbox.swift index c76383cb..a995f374 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Checkbox.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Checkbox.swift @@ -158,6 +158,7 @@ import MVMCore super.init(frame: frame) accessibilityTraits = .button + isAccessibilityElement = true accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "checkbox_action_hint") updateAccessibilityLabel() } @@ -198,8 +199,6 @@ import MVMCore open override func setupView() { super.setupView() - guard constraints.isEmpty else { return } - isUserInteractionEnabled = true translatesAutoresizingMaskIntoConstraints = false backgroundColor = .clear @@ -390,8 +389,6 @@ import MVMCore widthConstraint?.constant = dimension heightConstraint?.constant = dimension } - - //layoutIfNeeded() } public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { diff --git a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift index 40c34b08..7fec5960 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift @@ -323,6 +323,7 @@ public typealias ActionBlock = () -> () text = labelModel.text hero = labelModel.hero Label.setLabel(self, withHTML: labelModel.html) + isAccessibilityElement = hasText switch labelModel.textAlignment { case .center: @@ -429,6 +430,7 @@ public typealias ActionBlock = () -> () continue } } + attributedText = attributedString originalAttributedString = attributedText } diff --git a/MVMCoreUI/Atomic/Atoms/Views/Toggle.swift b/MVMCoreUI/Atomic/Atoms/Views/Toggle.swift index 3d9a2f21..8ab7b07b 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Toggle.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Toggle.swift @@ -127,6 +127,7 @@ public typealias ActionBlockConfirmation = () -> (Bool) private var widthConstraint: NSLayoutConstraint? private func constrainKnob() { + knobLeadingConstraint?.isActive = !isOn knobTrailingConstraint?.isActive = isOn } @@ -189,8 +190,11 @@ public typealias ActionBlockConfirmation = () -> (Bool) public override func setupView() { super.setupView() - guard subviews.isEmpty else { return } + isAccessibilityElement = true + accessibilityTraits = .button + accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "AccToggleHint") + accessibilityLabel = MVMCoreUIUtility.hardcodedString(withKey: "Toggle_buttonlabel") heightConstraint = heightAnchor.constraint(equalToConstant: Self.containerSize.height) heightConstraint?.isActive = true @@ -214,8 +218,6 @@ public typealias ActionBlockConfirmation = () -> (Bool) knobTrailingConstraint = trailingAnchor.constraint(equalTo: knobView.trailingAnchor, constant: 1) knobLeadingConstraint = knobView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 1) knobLeadingConstraint?.isActive = true - - accessibilityLabel = MVMCoreUIUtility.hardcodedString(withKey: "Toggle_buttonlabel") } public override func reset() { @@ -336,15 +338,13 @@ public typealias ActionBlockConfirmation = () -> (Bool) // MARK:- MoleculeViewProtocol public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - guard let toggleModel = model as? ToggleModel else { - return - } - - self.model = model + super.set(with: model, delegateObject, additionalData) self.delegateObject = delegateObject - FormValidator.setupValidation(molecule: toggleModel, delegate: delegateObject?.formHolderDelegate) guard let model = model as? ToggleModel else { return } + + FormValidator.setupValidation(molecule: model, delegate: delegateObject?.formHolderDelegate) + if let color = model.onTintColor?.uiColor { containerTintColor?.on = color } diff --git a/MVMCoreUI/Atomic/Atoms/Views/ToggleModel.swift b/MVMCoreUI/Atomic/Atoms/Views/ToggleModel.swift index 9e9e9e4a..8b7a87ed 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/ToggleModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/ToggleModel.swift @@ -12,11 +12,12 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo public static var identifier: String = "toggle" public var backgroundColor: Color? - public var state: Bool = true + public var state: Bool = false public var animated: Bool = true public var enabled: Bool = true public var action: ActionModelProtocol? public var alternateAction: ActionModelProtocol? + public var accessibilityText: String? public var fieldKey: String? public var groupName: String? = FormValidator.defaultGroupName public var baseValue: AnyHashable? @@ -25,6 +26,10 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo public var onKnobTintColor: Color? public var offKnobTintColor: Color? + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case moleculeName case state @@ -35,22 +40,36 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo case fieldKey case alternateAction case groupName + case accessibilityText case onTintColor case offTintColor case onKnobTintColor case offKnobTintColor } + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + public func formFieldValue() -> AnyHashable? { return state } + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + public init(_ state: Bool) { self.state = state } + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + if let state = try typeContainer.decodeIfPresent(Bool.self, forKey: .state) { self.state = state } @@ -71,6 +90,8 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { self.groupName = groupName } + + accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) } public func encode(to encoder: Encoder) throws { @@ -88,5 +109,6 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo try container.encodeIfPresent(offKnobTintColor, forKey: .offKnobTintColor) try container.encodeIfPresent(fieldKey, forKey: .fieldKey) try container.encodeIfPresent(groupName, forKey: .groupName) + try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText) } } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinks.swift index 85558caa..448d76e1 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxAllTextAndLinks.swift @@ -9,11 +9,18 @@ import Foundation @objcMembers open class ListLeftVariableCheckboxAllTextAndLinks: TableViewCell { - public let checkbox = Checkbox(frame: .zero) + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public let checkbox = Checkbox() public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero) public var stack: Stack + //-------------------------------------------------- // MARK: - Initializers + //-------------------------------------------------- + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { stack = Stack.createStack(with: [(view: checkbox, model: StackItemModel(horizontalAlignment: .fill)), (view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .leading))], @@ -25,17 +32,25 @@ import Foundation fatalError("init(coder:) has not been implemented") } - // MARK: - View Lifecycle + //-------------------------------------------------- + // MARK: - Life Cycle + //-------------------------------------------------- + override open func setupView() { super.setupView() addMolecule(stack) stack.restack() } - // MARK:- MoleculeViewProtocol - open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + //-------------------------------------------------- + // MARK: - MVMCoreUIMoleculeViewProtocol + //-------------------------------------------------- + + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) - guard let model = model as? ListLeftVariableCheckboxAllTextAndLinksModel else { return} + + guard let model = model as? ListLeftVariableCheckboxAllTextAndLinksModel else { return } + checkbox.set(with: model.checkbox, delegateObject, additionalData) eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData) } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethod.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethod.swift index be918aca..9517acf0 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethod.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonAndPaymentMethod.swift @@ -9,10 +9,10 @@ import UIKit @objcMembers open class ListLeftVariableRadioButtonAndPaymentMethod: TableViewCell { - //----------------------------------------------------- // MARK: - Outlets //----------------------------------------------------- + let radioButton = RadioButton(frame: .zero) let leftImage = MFLoadImageView(pinnedEdges: .all) let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink() @@ -21,6 +21,7 @@ import UIKit //----------------------------------------------------- // MARK: - Initializers //----------------------------------------------------- + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { stack = Stack.createStack(with: [(view: radioButton, model: StackItemModel(horizontalAlignment: .fill)), (view: leftImage, model: StackItemModel(horizontalAlignment: .fill)), @@ -36,6 +37,7 @@ import UIKit //----------------------------------------------------- // MARK: - View Lifecycle //----------------------------------------------------- + override open func setupView() { super.setupView() leftImage.addSizeConstraintsForAspectRatio = true @@ -54,6 +56,7 @@ import UIKit //---------------------------------------------------- // MARK: - Molecule //---------------------------------------------------- + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { super.set(with: model, delegateObject, additionalData) guard let model = model as? ListLeftVariableRadioButtonAndPaymentMethodModel else { return} diff --git a/MVMCoreUI/Atomic/Molecules/Items/StackItemModel.swift b/MVMCoreUI/Atomic/Molecules/Items/StackItemModel.swift index 12254fb5..436ed9cd 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/StackItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/StackItemModel.swift @@ -9,6 +9,10 @@ import Foundation @objcMembers public class StackItemModel: ContainerModel, StackItemModelProtocol, MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "simpleStackItem" public var moleculeName: String = StackItemModel.identifier public var backgroundColor: Color? @@ -16,12 +20,18 @@ import Foundation public var percent: Int? public var gone: Bool = false + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + public convenience init(spacing: CGFloat? = nil, percent: Int? = nil, horizontalAlignment: UIStackView.Alignment? = nil, verticalAlignment: UIStackView.Alignment? = nil, gone: Bool? = nil) { self.init() + self.horizontalAlignment = horizontalAlignment self.verticalAlignment = verticalAlignment self.spacing = spacing self.percent = percent + if let gone = gone { self.gone = gone } diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift index ebe54017..82f83530 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLink.swift @@ -19,7 +19,7 @@ import UIKit public let body = Label.commonLabelB2(true) public let link = Link() - var casteModel: EyebrowHeadlineBodyLinkModel? { + var castModel: EyebrowHeadlineBodyLinkModel? { get { return model as? EyebrowHeadlineBodyLinkModel } } @@ -59,10 +59,10 @@ import UIKit open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) - eyebrow.setOptional(with: casteModel?.eyebrow, delegateObject, additionalData) - headline.setOptional(with: casteModel?.headline, delegateObject, additionalData) - body.setOptional(with: casteModel?.body, delegateObject, additionalData) - link.setOptional(with: casteModel?.link, delegateObject, additionalData) + eyebrow.setOptional(with: castModel?.eyebrow, delegateObject, additionalData) + headline.setOptional(with: castModel?.headline, delegateObject, additionalData) + body.setOptional(with: castModel?.body, delegateObject, additionalData) + link.setOptional(with: castModel?.link, delegateObject, additionalData) // Hide labels if neeeded. stack.stackModel?.molecules[0].gone = !eyebrow.hasText diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBody.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBody.swift index c5a7f8c6..b36525f9 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBody.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBody.swift @@ -9,6 +9,7 @@ import UIKit open class HeadlineBody: View { + let headlineLabel = Label.commonLabelH2(true) let messageLabel = Label.commonLabelB2(true) var spaceBetweenLabelsConstant = PaddingOne @@ -71,8 +72,6 @@ open class HeadlineBody: View { open override func setupView() { super.setupView() - - guard subviews.isEmpty else { return } backgroundColor = .clear clipsToBounds = true @@ -81,6 +80,10 @@ open class HeadlineBody: View { addSubview(view) NSLayoutConstraint.constraintPinSubview(toSuperview: view) + view.isAccessibilityElement = false + view.shouldGroupAccessibilityChildren = true + view.accessibilityElements = [headlineLabel, messageLabel] + view.addSubview(headlineLabel) view.addSubview(messageLabel) diff --git a/MVMCoreUI/Atomic/Organisms/Stack.swift b/MVMCoreUI/Atomic/Organisms/Stack.swift index 23797927..e957a2a6 100644 --- a/MVMCoreUI/Atomic/Organisms/Stack.swift +++ b/MVMCoreUI/Atomic/Organisms/Stack.swift @@ -15,10 +15,11 @@ open class Stack: Container where T: (StackModelProtocol & MoleculeModelProto //-------------------------------------------------- open var contentView: UIView = MVMCoreUICommonViewsUtility.commonView() + open var stackItems: [UIView] = [] + open var stackModel: T? { get { return model as? T } } - open var stackItems: [UIView] = [] //-------------------------------------------------- // MARK: - Helpers @@ -37,15 +38,21 @@ open class Stack: Container where T: (StackModelProtocol & MoleculeModelProto guard let stackModel = stackModel else { return } let stackItems = self.stackItems self.stackItems = [] - let lastItemIndex = stackModel.molecules.lastIndex(where: { (item) -> Bool in - return !item.gone - }) + let lastItemIndex = stackModel.molecules.lastIndex { !$0.gone } // Adds the views let totalSpace = getTotalSpace() for (index, view) in stackItems.enumerated() { addView(view, stackModel.molecules[index], totalSpacing: totalSpace, lastItem: lastItemIndex == index) } + + isAccessibilityElement = false + var accessibleViews: [Any] = [] + for (index, view) in stackItems.enumerated() where !stackModel.molecules[index].gone { + accessibleViews.append(view) + } + + accessibilityElements = accessibleViews } /// Removes all stack items views from the view. diff --git a/MVMCoreUI/BaseClasses/Control.swift b/MVMCoreUI/BaseClasses/Control.swift index 7491f007..ebb88977 100644 --- a/MVMCoreUI/BaseClasses/Control.swift +++ b/MVMCoreUI/BaseClasses/Control.swift @@ -12,6 +12,7 @@ import UIKit //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- + open var model: MoleculeModelProtocol? private var initialSetupPerformed = false @@ -81,7 +82,7 @@ extension Control: AppleGuidelinesProtocol { // MARK: - MVMCoreViewProtocol extension Control: MVMCoreViewProtocol { - open func updateView(_ size: CGFloat) {} + open func updateView(_ size: CGFloat) { } /// Will be called only once. open func setupView() { diff --git a/MVMCoreUI/BaseClasses/TableViewCell.swift b/MVMCoreUI/BaseClasses/TableViewCell.swift index 060c2319..dc4d270a 100644 --- a/MVMCoreUI/BaseClasses/TableViewCell.swift +++ b/MVMCoreUI/BaseClasses/TableViewCell.swift @@ -197,10 +197,13 @@ import UIKit // MARK: - Caret View /// Adds the standard mvm style caret to the accessory view @objc public func addCaretViewAccessory() { + guard accessoryView == nil else { return } let caret = CaretView(lineWidth: 1) caret.translatesAutoresizingMaskIntoConstraints = true + caret.isAccessibilityElement = true + caret.accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "AccTabHint") caret.size = .small(.vertical) if let size = caret.size?.dimensions() { caret.frame = CGRect(origin: CGPoint.zero, size: size) @@ -246,7 +249,7 @@ import UIKit // MARK: - MoleculeListCellProtocol /// For when the separator between cells shows using json and frequency. Default is type: standard, frequency: allExceptTop. - public func setLines(with model: LineModel?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?, indexPath: IndexPath) { + public func setLines(with model: LineModel?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?, indexPath: IndexPath) { addSeparatorsIfNeeded() if let model = model { topSeparatorView?.set(with: model, delegateObject, additionalData) @@ -258,7 +261,7 @@ import UIKit setSeparatorFrequency(model?.frequency ?? .allExceptTop, indexPath: indexPath) } - public func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { + public func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { //TODO: Use object when handleAction is rewrote to handle action model if let actionMap = self.listItemModel?.action?.toJSON() { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) diff --git a/MVMCoreUI/Containers/Views/Container/ContainerModel.swift b/MVMCoreUI/Containers/Views/Container/ContainerModel.swift index a18e8589..ec6f9769 100644 --- a/MVMCoreUI/Containers/Views/Container/ContainerModel.swift +++ b/MVMCoreUI/Containers/Views/Container/ContainerModel.swift @@ -9,6 +9,10 @@ import Foundation open class ContainerModel: ContainerModelProtocol, Codable { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public var horizontalAlignment: UIStackView.Alignment? public var verticalAlignment: UIStackView.Alignment? public var useHorizontalMargins: Bool? @@ -17,6 +21,10 @@ open class ContainerModel: ContainerModelProtocol, Codable { public var topMarginPadding: CGFloat? public var bottomMarginPadding: CGFloat? + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case verticalAlignment case horizontalAlignment @@ -26,6 +34,10 @@ open class ContainerModel: ContainerModelProtocol, Codable { case bottomMarginPadding } + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + public init() {} public convenience init(horizontalAlignment: UIStackView.Alignment? = nil, verticalAlignment: UIStackView.Alignment? = nil) { @@ -33,6 +45,10 @@ open class ContainerModel: ContainerModelProtocol, Codable { self.horizontalAlignment = horizontalAlignment self.verticalAlignment = verticalAlignment } + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) diff --git a/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings b/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings index b9d21b67..48cbe3ce 100644 --- a/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings +++ b/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings @@ -6,52 +6,73 @@ Copyright © 2017 myverizon. All rights reserved. */ -//// Accessibility +// MARK: Accessibility "AccCloseButton" = "Close"; "swipe_to_select_with_action_hint" = "swipe up or down to select action, then double tap to select."; -// Tab + + +// MARK: Tab "AccTab" = ", tab"; "AccTabHint" = "Double tap to select."; "AccTabIndex" = ", %ld of %ld"; -// top alert + + +// MARK: Top alert "toptabbar_tab_selected" = ", tab, Selected"; "AccTopAlertClosed" = "Top alert notification is closed."; "top_alert_notification" = "Top alert notification"; -// Textfield + + +// MARK: Textfield "textfield_today_string" = "Today"; "textfield_error_message" = "%@.\n The error message.\n %@"; "textfield_picker_item" = " picker item"; "textfield_regular" = " regular"; "textfield_disabled_state" = "disabled"; -// MDNTextfield + + +// MARK: MDNTextfield "textfield_contacts_barbutton" = "My Contacts"; "textfield_phone_format_error_message" = "Invalid phone number format."; -// DigitTextfield + + +// MARK: DigitTextfield "mfdigittextfield_regular" = " regular"; -// Camera + + +// MARK: Camera "AccCameraButton" = "Camera Button"; "AccCameraHint" = "Double tap to launch camera for scanning"; -// Checkbox + + +// MARK: Checkbox "checkbox_action_hint" = "Double tap to change state"; "checkbox_checked_state" = "Checked"; "checkbox_unchecked_state" = "Unchecked"; "checkbox_desc_state" = "%@ CheckBox %@"; -// Radio Button + +// MARK: Radio Button "radio_action_hint" = "Double tap to select"; "radio_selected_state" = "Selected"; "radio_not_selected_state" = "Not Selected"; "radio_desc_state" = "Option"; -// Switch + +// MARK: Switch / Toggle "mfswitch_buttonlabel" = "Switch Button"; +"Toggle_buttonlabel" = "Toggle Button"; "AccOn" = "on"; "AccOff" = "off"; "AccToggleHint" = "double tap to toggle"; -// Carousel + + +// MARK: Carousel "MVMCoreUIPageControl_currentpage_index" = "page %ld of %ld"; "MVMCoreUIPageControlslides_currentpage_index" = "slide %ld of %ld"; -//Styler + + +// MARK: Styler "CountDownDay" = " day"; "CountDownHour" = " hour"; "CountDownMin" = " min";