updated operation type

This commit is contained in:
Krishna Kishore Bandaru 2023-07-21 12:43:15 +05:30
parent e77da88713
commit 646210f1a3

View File

@ -21,8 +21,10 @@ public enum AccessibilityNotificationType: String, Codable {
//By default from iOS 13+ focus is getting shifted to first interactive element inside viewcontroller not to the navigationitem left barbutton item so posting layoutChanged notification with delay to push to leftbarbutton item on new screen push
var delay: Double {
switch self {
case .controllerChanged, .webPageLoaded:
case .controllerChanged:
return 1.5
case .webPageLoaded:
return 2.0
case .screenChanged, .layoutChanged:
return 0.0
default:
@ -44,35 +46,40 @@ public enum AccessibilityNotificationType: String, Codable {
}
}
public typealias ArgumentHandler = ((NavigationOperationType?) -> Any?)
public class AccessbilityOperation: MVMCoreOperation {
let argument: Any?
let notificationType: AccessibilityNotificationType
private let operationType: NavigationOperationType
private let argumentHandler: ArgumentHandler?
private let notificationType: AccessibilityNotificationType
private var timerSource: DispatchSourceTimer?
public init(notificationType: AccessibilityNotificationType, argument: Any?) {
public init(notificationType: AccessibilityNotificationType, operationType: NavigationOperationType = .default, argumentHandler: ArgumentHandler?) {
self.notificationType = notificationType
self.argument = argument
self.argumentHandler = argumentHandler
self.operationType = operationType
}
public override func main() {
Task { @MainActor in
guard UIAccessibility.isVoiceOverRunning, !checkAndHandleForCancellation() else {
stop()
return
}
timerSource = DispatchSource.makeTimerSource()
timerSource?.setEventHandler { [weak self] in
guard UIAccessibility.isVoiceOverRunning, !checkAndHandleForCancellation() else {
stop()
return
}
timerSource = DispatchSource.makeTimerSource()
timerSource?.setEventHandler {
Task { @MainActor [weak self] in
if !(self?.isCancelled ?? false), let notification = self?.notificationType.accessibilityNotification {
UIAccessibility.post(notification: notification, argument: self?.argument)
print("argumentHandler \(self?.argumentHandler?(self?.operationType))")
UIAccessibility.post(notification: notification, argument: self?.argumentHandler?(self?.operationType))
self?.markAsFinished()
} else {
self?.stop()
}
}
timerSource?.schedule(deadline: .now() + notificationType.delay)
timerSource?.activate()
}
timerSource?.schedule(deadline: .now() + notificationType.delay)
timerSource?.activate()
}
public func stop() {
@ -82,6 +89,8 @@ public class AccessbilityOperation: MVMCoreOperation {
}
}
public enum NavigationOperationType { case `default`, tab }
open class AccessibilityHandler {
public static func shared() -> Self? {
@ -126,15 +135,18 @@ open class AccessibilityHandler {
//Since foucs shifted to other elements cancelling existing focus shift notifications if any
NotificationCenter.default.publisher(for: UIAccessibility.elementFocusedNotification)
.sink { [weak self] notification in
print("testing \(UIAccessibility.focusedElement(using: .notificationVoiceOver))")
print("testing \(notification.userInfo)")
self?.cancelAllOperations()
}.store(in: &anyCancellable)
}
private func registerForTopNotificationsChanges() {
NotificationHandler.shared()?.onNotificationWillShow.sink { [weak self] (_, model) in
self?.hasTopNotitificationInPage = true
self?.capturePreviousFocusElement(for: model.molecule)
}.store(in: &anyCancellable)
NotificationHandler.shared()?.onNotificationWillShow
.sink { [weak self] (_, model) in
self?.hasTopNotitificationInPage = true
self?.capturePreviousFocusElement(for: model.molecule)
}.store(in: &anyCancellable)
NotificationHandler.shared()?.onNotificationShown
.sink { [weak self] (view, model) in
self?.post(notification: .layoutChanged, argument: view)
@ -147,7 +159,6 @@ open class AccessibilityHandler {
.sink { [weak self] (view, model) in
self?.postAccessbilityToPrevElement(for: model.molecule)
}.store(in: &anyCancellable)
print(anyCancellable)
}
open func capturePreviousFocusElement(for model: MoleculeModelProtocol) {
@ -166,13 +177,15 @@ open class AccessibilityHandler {
accessibilityOperationQueue.cancelAllOperations()
}
open func post(webpageChanged type: AccessibilityNotificationType, argument: Any? = nil) {
post(notification: type, argument: argument)
open func post(webpageChanged type: AccessibilityNotificationType) {
post(notification: type)
}
public func post(notification type: AccessibilityNotificationType, argument: Any? = nil) {
public func post(notification type: AccessibilityNotificationType, operationType: NavigationOperationType = .default, argument: Any? = nil) {
guard UIAccessibility.isVoiceOverRunning else { return }
let accessbilityOperation = AccessbilityOperation(notificationType: type, argument: argument)
let accessbilityOperation = AccessbilityOperation(notificationType: type, operationType: operationType) { [weak self] in
($0 == .tab) ? self?.getFirstFocusedElementOnScreen() : argument
}
add(operation: accessbilityOperation)
}
@ -187,16 +200,17 @@ open class AccessibilityHandler {
extension AccessibilityHandler: MVMCorePresentationDelegateProtocol {
public func navigationController(_ navigationController: UINavigationController, prepareDisplayFor viewController: UIViewController) {
open func navigationController(_ navigationController: UINavigationController, prepareDisplayFor viewController: UIViewController) {
previousAccessiblityElement = nil
delegate = viewController as? MVMCoreViewControllerProtocol
if let announcementText {
let accessbilityOperation = AccessbilityOperation(notificationType: .announcement, argument: announcementText)
let accessbilityOperation = AccessbilityOperation(notificationType: .announcement) { _ in announcementText }
add(operation: accessbilityOperation)
}
}
public func navigationController(_ navigationController: UINavigationController, displayedViewController viewController: UIViewController) {
@MainActor
open func navigationController(_ navigationController: UINavigationController, displayedViewController viewController: UIViewController) {
guard UIAccessibility.isVoiceOverRunning,
canPostAccessbilityNotification(for: viewController) else { return }
//TODO: - For Tabbar change: adding 1.5 sec delay to shift focus to the top. for Temp fix added to check on childern count
@ -208,7 +222,8 @@ extension AccessibilityHandler: MVMCorePresentationDelegateProtocol {
previousAccessiblityElement = getFirstFocusedElementOnScreen()
} else {
let accessbilityElement = getAccessbilityFocusedElement()
post(notification: navigationController.children.count == 1 ? .controllerChanged : .layoutChanged, argument: accessbilityElement ?? getFirstFocusedElementOnScreen())
let operationType: NavigationOperationType = navigationController.children.count == 1 ? .tab : .default //TODO: - need to identify the operationType
post(notification: operationType == .tab ? .controllerChanged : .layoutChanged, operationType: operationType, argument: accessbilityElement ?? getFirstFocusedElementOnScreen())
accessibilityId = nil
}
}