Added rotor for checkbox

This commit is contained in:
Krishna Kishore Bandaru 2023-10-16 18:48:49 +05:30
parent cb50234090
commit f73dbee190
2 changed files with 34 additions and 14 deletions

View File

@ -13,6 +13,7 @@ fileprivate enum RotorType: String, CaseIterable {
case button = "Buttons"
case header = "Header"
case checkbox = "Checkbox"
var trait: UIAccessibilityTraits {
switch self {
@ -20,6 +21,26 @@ fileprivate enum RotorType: String, CaseIterable {
return .button
case .header:
return .header
default:
return .none
}
}
var modelFilter: ((MoleculeModelProtocol) -> Bool) {
switch self {
case .checkbox:
return { $0 is CheckboxModel }
default:
return { $0.accessibilityTraits?.contains(trait) ?? false }
}
}
var filter: ((UIView) -> Bool) {
switch self {
case .checkbox:
return { $0 is Checkbox }
default:
return { $0.accessibilityTraits.contains(trait) }
}
}
@ -35,7 +56,7 @@ fileprivate enum RotorType: String, CaseIterable {
}
}
public protocol RotorViewElementsProtocol: UIViewController {
public protocol RotorViewElementsProtocol: MVMCoreViewControllerProtocol {
var topView: UIView? { get set }
var middleView: UIView? { get set }
var bottomView: UIView? { get set }
@ -89,7 +110,7 @@ class RotorHandler {
private func identifyAndPrepareRotors(_ delegateObject: MVMCoreUIDelegateObject?) {
guard UIAccessibility.isVoiceOverRunning,
let currentViewController = (delegateObject?.moleculeDelegate as? (MVMCoreViewControllerProtocol & UIViewController)) else { return }
let currentViewController = (delegateObject?.moleculeDelegate as? (MVMCoreViewControllerProtocol & UIViewController)) else { return }
var customRotors: [UIAccessibilityCustomRotor] = []
for type in RotorType.allCases {
if let elements = getTraitMappedElements(currentViewController, type: type),
@ -111,34 +132,32 @@ class RotorHandler {
accessibilityElements.append(contentsOf: rotorElements)
}
if let tabBarHidden = (template as? TabPageModelProtocol)?.tabBarHidden, !tabBarHidden {
accessibilityElements.append(contentsOf: (MVMCoreUISplitViewController.main()?.tabBar?.subviews ?? []).filter {
$0.accessibilityTraits.contains(type.trait)
})
accessibilityElements.append(contentsOf: (MVMCoreUISplitViewController.main()?.tabBar?.subviews ?? []).filter { type.filter($0) })
}
return accessibilityElements.compactMap { $0 }
}
private func getRotorElementsFrom(manager: (MVMCoreViewControllerProtocol & UIViewController)?, type: RotorType) -> [Any]? {
guard let elements = (manager as? MVMCoreViewManagerProtocol)?.getAccessibilityElements() as? [UIView] else { return nil }
return MVMCoreUIUtility.findViews(by: MoleculeViewProtocol.self, views: elements).filter { $0.accessibilityTraits.contains(type.trait) } as [Any]
return MVMCoreUIUtility.findViews(by: MoleculeViewProtocol.self, views: elements).filter { type.filter($0) } as [Any]
}
private func getRotorElementsFrom(template: (MVMCoreViewControllerProtocol & UIViewController)?, type: RotorType) -> [Any]? {
guard let template = template as? (RotorViewElementsProtocol & MVMCoreViewControllerProtocol & UIViewController) else {
return MVMCoreUIUtility.findViews(by: UIView.self, views: [template?.view].compactMap { $0 }).filter { $0.accessibilityTraits.contains(type.trait) } as [Any]
return MVMCoreUIUtility.findViews(by: UIView.self, views: [template?.view].compactMap { $0 }).filter { type.filter($0) } as [Any]
}
let topViewRotorElements = MVMCoreUIUtility.findViews(by: UIView.self, views: [template.topView].compactMap { $0 }).filter { $0.accessibilityTraits.contains(type.trait) } as [Any]
let topViewRotorElements = MVMCoreUIUtility.findViews(by: UIView.self, views: [template.topView].compactMap { $0 }).filter { type.filter($0) } as [Any]
var reusableViewRotorElements: [Any] = []
if let middleView = template.middleView {
if middleView.isKind(of: UITableView.self),
let template = template as? (any MoleculeListProtocol & ViewController) {
reusableViewRotorElements = getRotorElements(from: template, type: type) ?? []
} else {
reusableViewRotorElements = MVMCoreUIUtility.findViews(by: UIView.self, views: [middleView].compactMap { $0 }).filter { $0.accessibilityTraits.contains(type.trait) } as [Any]
reusableViewRotorElements = MVMCoreUIUtility.findViews(by: UIView.self, views: [middleView].compactMap { $0 }).filter { type.filter($0) } as [Any]
}
}
let bottomViewRotorElements = MVMCoreUIUtility.findViews(by: UIView.self, views: [template.bottomView].compactMap { $0 }).filter { $0.accessibilityTraits.contains(type.trait) } as [Any]
let remainingRotorElements = MVMCoreUIUtility.findViews(by: UIView.self, views: [template.view], excludedViews: [template.topView, template.middleView, template.middleView, template.bottomView].compactMap { $0 }).filter { $0.accessibilityTraits.contains(type.trait) } as [Any]
let bottomViewRotorElements = MVMCoreUIUtility.findViews(by: UIView.self, views: [template.bottomView].compactMap { $0 }).filter { type.filter($0) } as [Any]
let remainingRotorElements = MVMCoreUIUtility.findViews(by: UIView.self, views: [template.view], excludedViews: [template.topView, template.middleView, template.middleView, template.bottomView].compactMap { $0 }).filter { type.filter($0) } as [Any]
return topViewRotorElements + reusableViewRotorElements + remainingRotorElements + bottomViewRotorElements
}
@ -152,7 +171,7 @@ class RotorHandler {
traitIndexPath = indexPath
}
var result = result
if (model.accessibilityTraits?.contains(type.trait) ?? false), let traitIndexPath {
if type.modelFilter(model), let traitIndexPath {
result.append(.init(indexPath: traitIndexPath, model: model))
}
return result
@ -179,7 +198,7 @@ class RotorHandler {
let controller = self.delegate as? RotorListTypeDelegateProtocol {
controller.scrollToRow(at: element.indexPath, at: .middle, animated: false)
guard let cellView = controller.cellForRow(at: element.indexPath) else { return UIAccessibilityCustomRotorItemResult() }
rotorElement = MVMCoreUIUtility.findViews(by: MoleculeViewProtocol.self, views: [cellView]).filter { $0.accessibilityTraits.contains(type.trait) && $0.model?.id == element.model.id }.first as Any
rotorElement = MVMCoreUIUtility.findViews(by: MoleculeViewProtocol.self, views: [cellView]).filter { type.filter($0) && $0.model?.id == element.model.id }.first as Any
} else {
if let viewElement = (rotorElement as? UIView) {
let convertedFrame = viewElement.convert(viewElement.frame, to: (self.delegate as? UIViewController)?.view)

View File

@ -15,7 +15,7 @@ public enum CheckboxPosition: String, Codable {
case bottom
}
@objcMembers open class CheckboxLabelModel: MoleculeModelProtocol {
@objcMembers open class CheckboxLabelModel: MoleculeModelProtocol, ParentMoleculeModelProtocol {
open class var identifier: String { "checkboxLabel" }
public var moleculeName: String = CheckboxLabelModel.identifier
@DecodableDefault.UUIDString public var id: String
@ -25,6 +25,7 @@ public enum CheckboxPosition: String, Codable {
public var checkbox: CheckboxModel
public var label: LabelModel
public var children: [MoleculeModelProtocol] { [checkbox, label] }
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------