I've built a streaming audio app that looks like this:
When the stream is lost, I overlay this screen:
My issue is that with Voiceover ON, all the underlying controls are still active: I can swipe to them all, and adjust their value.
Here is a snippet of my code for when the signal is lost and regained:
@objc func lostStream() {
DispatchQueue.main.async {
self.lossOfSignalBlocker.alpha = 0.0
self.lossOfSignalBlocker.frame = self.view.bounds
self.view.addSubview(self.lossOfSignalBlocker)
self.lossOfSignalBlocker.isUserInteractionEnabled = true
//UIView.animate(withDuration: 0.2) { self.lossOfSignalBlocker.alpha = 1.0 }
UIView.animate( withDuration: 0.2, animations: { self.lossOfSignalBlocker.alpha = 1.0 } )
//Announce loss of signal to Voiceover user.
UIAccessibilityPostNotification(
UIAccessibilityAnnouncementNotification,
"Signal Lost" as NSString
)
}
}
@objc func regainedStream() {
DispatchQueue.main.async {
UIView.animate( withDuration: 0.2, animations: { self.lossOfSignalBlocker.alpha = 0.0 } )
{ _ in
self.lossOfSignalBlocker.removeFromSuperview()
}
}
}
How do I disable the main UI so that only the overlay responds to any Voiceover-related actions?
OK! I've made it work. In addition to setting 'accessibilityElementsHidden' to TRUE, you have to tell the app that the screen has changed by calling 'UIAccessibilityPostNotification' with the 'UIAccessibilityScreenChangedNotification' notification.
Here's what that code looks like now:
@objc func lostStream() {
DispatchQueue.main.async {
self.lossOfSignalBlocker.alpha = 0.0
self.lossOfSignalBlocker.frame = self.view.bounds
self.view.addSubview(self.lossOfSignalBlocker)
self.lossOfSignalBlocker.isUserInteractionEnabled = true
UIView.animate( withDuration: 0.1, animations: { self.lossOfSignalBlocker.alpha = 1.0 } )
//Disable Voiceover accessibility controls in main view
self.tableView.accessibilityElementsHidden = true
//Notify app the screen has changed.
UIAccessibilityPostNotification(
UIAccessibilityScreenChangedNotification,
nil
)
//Announce loss of signal to Voiceover user.
UIAccessibilityPostNotification(
UIAccessibilityAnnouncementNotification,
"Signal Lost. Reconnecting." as NSString
)
}
}
@objc func regainedStream() {
DispatchQueue.main.async {
UIView.animate( withDuration: 0.2, animations: { self.lossOfSignalBlocker.alpha = 0.0 } )
{ _ in
self.lossOfSignalBlocker.removeFromSuperview()
}
//Re-enable Voiceover accessibility controls in main view
self.tableView.accessibilityElementsHidden = false
//Notify app the screen has changed.
UIAccessibilityPostNotification(
UIAccessibilityScreenChangedNotification,
nil
)
//Announce signal regained to Voiceover user.
UIAccessibilityPostNotification(
UIAccessibilityAnnouncementNotification,
"Reconnected." as NSString
)
}
}