From 552b4a26610d66a087465913aa7e9dc2c46b931a Mon Sep 17 00:00:00 2001 From: Peter <> Date: Tue, 5 Mar 2019 13:36:50 +0000 Subject: [PATCH] VoiceOver updates --- Display/AlertController.swift | 2 ++ Display/ContainableController.swift | 2 ++ Display/NavigationController.swift | 12 +++++++++- Display/PresentationContext.swift | 37 +++++++++++++++++++++++++++++ Display/TabBarController.swift | 11 ++++++++- Display/ViewController.swift | 1 + Display/WindowContent.swift | 4 ++++ 7 files changed, 67 insertions(+), 2 deletions(-) diff --git a/Display/AlertController.swift b/Display/AlertController.swift index f829250ba5..de34d7b060 100644 --- a/Display/AlertController.swift +++ b/Display/AlertController.swift @@ -68,6 +68,8 @@ open class AlertController: ViewController { super.init(navigationBarPresentationData: nil) + self.blocksBackgroundWhenInOverlay = true + self.statusBar.statusBarStyle = .Ignore } diff --git a/Display/ContainableController.swift b/Display/ContainableController.swift index 055fa46254..ec51a25542 100644 --- a/Display/ContainableController.swift +++ b/Display/ContainableController.swift @@ -4,8 +4,10 @@ import SwiftSignalKit public protocol ContainableController: class { var view: UIView! { get } + var displayNode: ASDisplayNode { get } var isViewLoaded: Bool { get } var isOpaqueWhenInOverlay: Bool { get } + var blocksBackgroundWhenInOverlay: Bool { get } var ready: Promise { get } func combinedSupportedOrientations(currentOrientationToLock: UIInterfaceOrientationMask) -> ViewControllerSupportedOrientations diff --git a/Display/NavigationController.swift b/Display/NavigationController.swift index 17bda998f1..97be54cde0 100644 --- a/Display/NavigationController.swift +++ b/Display/NavigationController.swift @@ -96,6 +96,7 @@ public enum NavigationControllerMode { open class NavigationController: UINavigationController, ContainableController, UIGestureRecognizerDelegate { public var isOpaqueWhenInOverlay: Bool = true + public var blocksBackgroundWhenInOverlay: Bool = true public var ready: Promise = Promise(true) @@ -140,6 +141,11 @@ open class NavigationController: UINavigationController, ContainableController, return self._viewControllers.last?.controller } + private var _displayNode: ASDisplayNode? + public var displayNode: ASDisplayNode { + return self._displayNode! + } + public init(mode: NavigationControllerMode, theme: NavigationControllerTheme) { self.mode = mode self.theme = theme @@ -594,7 +600,11 @@ open class NavigationController: UINavigationController, ContainableController, } open override func loadView() { - self.view = NavigationControllerView() + self._displayNode = ASDisplayNode(viewBlock: { + return NavigationControllerView() + }, didLoad: nil) + + self.view = self.displayNode.view self.view.clipsToBounds = true self.view.autoresizingMask = [] diff --git a/Display/PresentationContext.swift b/Display/PresentationContext.swift index 39a8922f40..766f6974de 100644 --- a/Display/PresentationContext.swift +++ b/Display/PresentationContext.swift @@ -33,6 +33,15 @@ final class PresentationContext { var updateIsInteractionBlocked: ((Bool) -> Void)? + var updateHasOpaqueOverlay: ((Bool) -> Void)? + private(set) var hasOpaqueOverlay: Bool = false { + didSet { + if self.hasOpaqueOverlay != oldValue { + self.updateHasOpaqueOverlay?(self.hasOpaqueOverlay) + } + } + } + private var layout: ContainerViewLayout? private var ready: Bool { @@ -56,6 +65,15 @@ final class PresentationContext { return false } + var currentlyBlocksBackgroundWhenInOverlay: Bool { + for (controller, _) in self.controllers { + if controller.isOpaqueWhenInOverlay || controller.blocksBackgroundWhenInOverlay { + return true + } + } + return false + } + private func topLevelSubview(for level: PresentationSurfaceLevel) -> UIView? { var topController: ContainableController? for (controller, controllerLevel) in self.controllers.reversed() { @@ -173,10 +191,12 @@ final class PresentationContext { controller.viewWillAppear(false) controller.viewDidAppear(false) } + strongSelf.updateViews() } })) } else { self.controllers.append((controller, level)) + self.updateViews() } } @@ -190,6 +210,7 @@ final class PresentationContext { controller.viewWillDisappear(false) controller.view.removeFromSuperview() controller.viewDidDisappear(false) + self.updateViews() } } @@ -227,6 +248,7 @@ final class PresentationContext { controller.containerLayoutUpdated(layout, transition: .immediate) controller.viewDidAppear(false) } + self.updateViews() } } @@ -238,6 +260,21 @@ final class PresentationContext { } } + private func updateViews() { + self.hasOpaqueOverlay = self.isCurrentlyOpaque + var topHasOpaque = false + for (controller, _) in self.controllers.reversed() { + if topHasOpaque { + controller.displayNode.accessibilityElementsHidden = true + } else { + if controller.isOpaqueWhenInOverlay || controller.blocksBackgroundWhenInOverlay { + topHasOpaque = true + } + controller.displayNode.accessibilityElementsHidden = false + } + } + } + func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { for (controller, _) in self.controllers.reversed() { if controller.isViewLoaded { diff --git a/Display/TabBarController.swift b/Display/TabBarController.swift index 3a5de78807..d671c6a3bb 100644 --- a/Display/TabBarController.swift +++ b/Display/TabBarController.swift @@ -329,7 +329,16 @@ open class TabBarController: ViewController { } |> filter { $0 } |> take(1) - self._ready.set(signals) + + let allReady = signals + |> deliverOnMainQueue + |> mapToSignal { _ -> Signal in + // wait for tab bar items to be applied + return .single(true) + |> delay(0.0, queue: Queue.mainQueue()) + } + + self._ready.set(allReady) if let updatedSelectedIndex = updatedSelectedIndex { self.selectedIndex = updatedSelectedIndex diff --git a/Display/ViewController.swift b/Display/ViewController.swift index c599f392e2..cddb0e2eda 100644 --- a/Display/ViewController.swift +++ b/Display/ViewController.swift @@ -74,6 +74,7 @@ open class ViewControllerPresentationArguments { } public final var isOpaqueWhenInOverlay: Bool = false + public final var blocksBackgroundWhenInOverlay: Bool = false public func combinedSupportedOrientations(currentOrientationToLock: UIInterfaceOrientationMask) -> ViewControllerSupportedOrientations { return self.supportedOrientations diff --git a/Display/WindowContent.swift b/Display/WindowContent.swift index c50a785e97..bc674b2c5f 100644 --- a/Display/WindowContent.swift +++ b/Display/WindowContent.swift @@ -370,6 +370,10 @@ public class Window1 { self?.isInteractionBlocked = value } + self.presentationContext.updateHasOpaqueOverlay = { [weak self] value in + self?._rootController?.displayNode.accessibilityElementsHidden = value + } + self.hostView.present = { [weak self] controller, level, blockInteraction, completion in self?.present(controller, on: level, blockInteraction: blockInteraction, completion: completion) }