Pass interface orientation updates to view controller

This commit is contained in:
Ilya Laktyushin 2019-03-15 20:54:22 +03:00
parent ca80cc40dc
commit 26d26bb3a5
9 changed files with 67 additions and 22 deletions

View File

@ -14,6 +14,7 @@ public protocol ContainableController: class {
var deferScreenEdgeGestures: UIRectEdge { get } var deferScreenEdgeGestures: UIRectEdge { get }
func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition)
func updateToInterfaceOrientation(_ orientation: UIInterfaceOrientation)
func viewWillAppear(_ animated: Bool) func viewWillAppear(_ animated: Bool)
func viewWillDisappear(_ animated: Bool) func viewWillDisappear(_ animated: Bool)

View File

@ -13,15 +13,15 @@ private final class ContextMenuContainerMaskView: UIView {
} }
} }
final class ContextMenuContainerNode: ASDisplayNode { public final class ContextMenuContainerNode: ASDisplayNode {
private var cachedMaskParams: CachedMaskParams? private var cachedMaskParams: CachedMaskParams?
private let maskView = ContextMenuContainerMaskView() private let maskView = ContextMenuContainerMaskView()
var relativeArrowPosition: (CGFloat, Bool)? public var relativeArrowPosition: (CGFloat, Bool)?
//private let effectView: UIVisualEffectView //private let effectView: UIVisualEffectView
override init() { override public init() {
//self.effectView = UIVisualEffectView(effect: UIBlurEffect(style: .light)) //self.effectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
super.init() super.init()
@ -32,19 +32,19 @@ final class ContextMenuContainerNode: ASDisplayNode {
self.view.mask = self.maskView self.view.mask = self.maskView
} }
override func didLoad() { override public func didLoad() {
super.didLoad() super.didLoad()
self.layer.allowsGroupOpacity = true self.layer.allowsGroupOpacity = true
} }
override func layout() { override public func layout() {
super.layout() super.layout()
self.updateLayout(transition: .immediate) self.updateLayout(transition: .immediate)
} }
func updateLayout(transition: ContainedViewLayoutTransition) { public func updateLayout(transition: ContainedViewLayoutTransition) {
//self.effectView.frame = self.bounds //self.effectView.frame = self.bounds
let maskParams = CachedMaskParams(size: self.bounds.size, relativeArrowPosition: self.relativeArrowPosition?.0 ?? self.bounds.size.width / 2.0, arrowOnBottom: self.relativeArrowPosition?.1 ?? true) let maskParams = CachedMaskParams(size: self.bounds.size, relativeArrowPosition: self.relativeArrowPosition?.0 ?? self.bounds.size.width / 2.0, arrowOnBottom: self.relativeArrowPosition?.1 ?? true)
@ -58,23 +58,23 @@ final class ContextMenuContainerNode: ASDisplayNode {
let arrowOnBottom = maskParams.arrowOnBottom let arrowOnBottom = maskParams.arrowOnBottom
path.move(to: CGPoint(x: 0.0, y: verticalInset + cornerRadius)) path.move(to: CGPoint(x: 0.0, y: verticalInset + cornerRadius))
path.addArc(withCenter: CGPoint(x: cornerRadius, y: verticalInset + cornerRadius), radius: cornerRadius, startAngle: CGFloat.pi, endAngle: CGFloat(3 * M_PI / 2), clockwise: true) path.addArc(withCenter: CGPoint(x: cornerRadius, y: verticalInset + cornerRadius), radius: cornerRadius, startAngle: CGFloat.pi, endAngle: CGFloat(3.0 * CGFloat.pi / 2.0), clockwise: true)
if !arrowOnBottom { if !arrowOnBottom {
path.addLine(to: CGPoint(x: arrowPosition - arrowWidth / 2.0, y: verticalInset)) path.addLine(to: CGPoint(x: arrowPosition - arrowWidth / 2.0, y: verticalInset))
path.addLine(to: CGPoint(x: arrowPosition, y: 0.0)) path.addLine(to: CGPoint(x: arrowPosition, y: 0.0))
path.addLine(to: CGPoint(x: arrowPosition + arrowWidth / 2.0, y: verticalInset)) path.addLine(to: CGPoint(x: arrowPosition + arrowWidth / 2.0, y: verticalInset))
} }
path.addLine(to: CGPoint(x: maskParams.size.width - cornerRadius, y: verticalInset)) path.addLine(to: CGPoint(x: maskParams.size.width - cornerRadius, y: verticalInset))
path.addArc(withCenter: CGPoint(x: maskParams.size.width - cornerRadius, y: verticalInset + cornerRadius), radius: cornerRadius, startAngle: CGFloat(3 * M_PI / 2), endAngle: 0.0, clockwise: true) path.addArc(withCenter: CGPoint(x: maskParams.size.width - cornerRadius, y: verticalInset + cornerRadius), radius: cornerRadius, startAngle: CGFloat(3.0 * CGFloat.pi / 2.0), endAngle: 0.0, clockwise: true)
path.addLine(to: CGPoint(x: maskParams.size.width, y: maskParams.size.height - cornerRadius - verticalInset)) path.addLine(to: CGPoint(x: maskParams.size.width, y: maskParams.size.height - cornerRadius - verticalInset))
path.addArc(withCenter: CGPoint(x: maskParams.size.width - cornerRadius, y: maskParams.size.height - cornerRadius - verticalInset), radius: cornerRadius, startAngle: 0.0, endAngle: CGFloat(M_PI / 2.0), clockwise: true) path.addArc(withCenter: CGPoint(x: maskParams.size.width - cornerRadius, y: maskParams.size.height - cornerRadius - verticalInset), radius: cornerRadius, startAngle: 0.0, endAngle: CGFloat(CGFloat.pi / 2.0), clockwise: true)
if arrowOnBottom { if arrowOnBottom {
path.addLine(to: CGPoint(x: arrowPosition + arrowWidth / 2.0, y: maskParams.size.height - verticalInset)) path.addLine(to: CGPoint(x: arrowPosition + arrowWidth / 2.0, y: maskParams.size.height - verticalInset))
path.addLine(to: CGPoint(x: arrowPosition, y: maskParams.size.height)) path.addLine(to: CGPoint(x: arrowPosition, y: maskParams.size.height))
path.addLine(to: CGPoint(x: arrowPosition - arrowWidth / 2.0, y: maskParams.size.height - verticalInset)) path.addLine(to: CGPoint(x: arrowPosition - arrowWidth / 2.0, y: maskParams.size.height - verticalInset))
} }
path.addLine(to: CGPoint(x: cornerRadius, y: maskParams.size.height - verticalInset)) path.addLine(to: CGPoint(x: cornerRadius, y: maskParams.size.height - verticalInset))
path.addArc(withCenter: CGPoint(x: cornerRadius, y: maskParams.size.height - cornerRadius - verticalInset), radius: cornerRadius, startAngle: CGFloat(M_PI / 2.0), endAngle: CGFloat(M_PI), clockwise: true) path.addArc(withCenter: CGPoint(x: cornerRadius, y: maskParams.size.height - cornerRadius - verticalInset), radius: cornerRadius, startAngle: CGFloat(CGFloat.pi / 2.0), endAngle: CGFloat(M_PI), clockwise: true)
path.close() path.close()
self.cachedMaskParams = maskParams self.cachedMaskParams = maskParams

View File

@ -158,6 +158,14 @@ final class GlobalOverlayPresentationContext {
return nil return nil
} }
func updateToInterfaceOrientation(_ orientation: UIInterfaceOrientation) {
if self.ready {
for controller in self.controllers {
controller.updateToInterfaceOrientation(orientation)
}
}
}
func combinedSupportedOrientations(currentOrientationToLock: UIInterfaceOrientationMask) -> ViewControllerSupportedOrientations { func combinedSupportedOrientations(currentOrientationToLock: UIInterfaceOrientationMask) -> ViewControllerSupportedOrientations {
var mask = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .all) var mask = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .all)

View File

@ -169,7 +169,7 @@ private final class NativeWindow: UIWindow, WindowHost {
var updateSize: ((CGSize) -> Void)? var updateSize: ((CGSize) -> Void)?
var layoutSubviewsEvent: (() -> Void)? var layoutSubviewsEvent: (() -> Void)?
var updateIsUpdatingOrientationLayout: ((Bool) -> Void)? var updateIsUpdatingOrientationLayout: ((Bool) -> Void)?
var updateToInterfaceOrientation: (() -> Void)? var updateToInterfaceOrientation: ((UIInterfaceOrientation) -> Void)?
var presentController: ((ContainableController, PresentationSurfaceLevel, Bool, @escaping () -> Void) -> Void)? var presentController: ((ContainableController, PresentationSurfaceLevel, Bool, @escaping () -> Void) -> Void)?
var presentControllerInGlobalOverlay: ((_ controller: ContainableController) -> Void)? var presentControllerInGlobalOverlay: ((_ controller: ContainableController) -> Void)?
var hitTestImpl: ((CGPoint, UIEvent?) -> UIView?)? var hitTestImpl: ((CGPoint, UIEvent?) -> UIView?)?
@ -246,7 +246,8 @@ private final class NativeWindow: UIWindow, WindowHost {
super._update(toInterfaceOrientation: arg1, duration: arg2, force: arg3) super._update(toInterfaceOrientation: arg1, duration: arg2, force: arg3)
self.updateIsUpdatingOrientationLayout?(false) self.updateIsUpdatingOrientationLayout?(false)
self.updateToInterfaceOrientation?() let orientation = UIInterfaceOrientation(rawValue: Int(arg1)) ?? .unknown
self.updateToInterfaceOrientation?(orientation)
} }
func present(_ controller: ContainableController, on level: PresentationSurfaceLevel, blockInteraction: Bool, completion: @escaping () -> Void) { func present(_ controller: ContainableController, on level: PresentationSurfaceLevel, blockInteraction: Bool, completion: @escaping () -> Void) {
@ -316,8 +317,8 @@ public func nativeWindowHostView() -> (UIWindow & WindowHost, WindowHostView) {
hostView?.isUpdatingOrientationLayout = value hostView?.isUpdatingOrientationLayout = value
} }
window.updateToInterfaceOrientation = { [weak hostView] in window.updateToInterfaceOrientation = { [weak hostView] orientation in
hostView?.updateToInterfaceOrientation?() hostView?.updateToInterfaceOrientation?(orientation)
} }
window.presentController = { [weak hostView] controller, level, blockInteraction, completion in window.presentController = { [weak hostView] controller, level, blockInteraction, completion in

View File

@ -599,6 +599,14 @@ open class NavigationController: UINavigationController, ContainableController,
} }
} }
public func updateToInterfaceOrientation(_ orientation: UIInterfaceOrientation) {
for record in self._viewControllers {
if let controller = record.controller as? ContainableController {
controller.updateToInterfaceOrientation(orientation)
}
}
}
open override func loadView() { open override func loadView() {
self._displayNode = ASDisplayNode(viewBlock: { self._displayNode = ASDisplayNode(viewBlock: {
return NavigationControllerView() return NavigationControllerView()

View File

@ -286,6 +286,14 @@ final class PresentationContext {
return nil return nil
} }
func updateToInterfaceOrientation(_ orientation: UIInterfaceOrientation) {
if self.ready {
for (controller, _) in self.controllers {
controller.updateToInterfaceOrientation(orientation)
}
}
}
func combinedSupportedOrientations(currentOrientationToLock: UIInterfaceOrientationMask) -> ViewControllerSupportedOrientations { func combinedSupportedOrientations(currentOrientationToLock: UIInterfaceOrientationMask) -> ViewControllerSupportedOrientations {
var mask = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .all) var mask = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .all)

View File

@ -74,16 +74,18 @@ public final class TooltipController: ViewController {
private let timeout: Double private let timeout: Double
private let dismissByTapOutside: Bool private let dismissByTapOutside: Bool
private let dismissImmediatelyOnLayoutUpdate: Bool
private var timeoutTimer: SwiftSignalKit.Timer? private var timeoutTimer: SwiftSignalKit.Timer?
private var layout: ContainerViewLayout? private var layout: ContainerViewLayout?
public var dismissed: (() -> Void)? public var dismissed: (() -> Void)?
public init(content: TooltipControllerContent, timeout: Double = 2.0, dismissByTapOutside: Bool = false) { public init(content: TooltipControllerContent, timeout: Double = 2.0, dismissByTapOutside: Bool = false, dismissImmediatelyOnLayoutUpdate: Bool = false) {
self.content = content self.content = content
self.timeout = timeout self.timeout = timeout
self.dismissByTapOutside = dismissByTapOutside self.dismissByTapOutside = dismissByTapOutside
self.dismissImmediatelyOnLayoutUpdate = dismissImmediatelyOnLayoutUpdate
super.init(navigationBarPresentationData: nil) super.init(navigationBarPresentationData: nil)
} }
@ -114,9 +116,10 @@ public final class TooltipController: ViewController {
super.containerLayoutUpdated(layout, transition: transition) super.containerLayoutUpdated(layout, transition: transition)
if self.layout != nil && self.layout! != layout { if self.layout != nil && self.layout! != layout {
self.dismissed?() if self.dismissImmediatelyOnLayoutUpdate {
self.controllerNode.animateOut { [weak self] in self.dismissImmediately()
self?.presentingViewController?.dismiss(animated: false) } else {
self.dismiss()
} }
} else { } else {
self.layout = layout self.layout = layout
@ -160,4 +163,9 @@ public final class TooltipController: ViewController {
completion?() completion?()
} }
} }
public func dismissImmediately() {
self.dismissed?()
self.presentingViewController?.dismiss(animated: false)
}
} }

View File

@ -327,6 +327,10 @@ open class ViewControllerPresentationArguments {
} }
} }
open func updateToInterfaceOrientation(_ orientation: UIInterfaceOrientation) {
}
public func setDisplayNavigationBar(_ displayNavigationBar: Bool, transition: ContainedViewLayoutTransition = .immediate) { public func setDisplayNavigationBar(_ displayNavigationBar: Bool, transition: ContainedViewLayoutTransition = .immediate) {
if displayNavigationBar != self.displayNavigationBar { if displayNavigationBar != self.displayNavigationBar {
self.displayNavigationBar = displayNavigationBar self.displayNavigationBar = displayNavigationBar

View File

@ -220,7 +220,7 @@ public final class WindowHostView {
var presentNative: ((UIViewController) -> Void)? var presentNative: ((UIViewController) -> Void)?
var updateSize: ((CGSize, Double) -> Void)? var updateSize: ((CGSize, Double) -> Void)?
var layoutSubviews: (() -> Void)? var layoutSubviews: (() -> Void)?
var updateToInterfaceOrientation: (() -> Void)? var updateToInterfaceOrientation: ((UIInterfaceOrientation) -> Void)?
var isUpdatingOrientationLayout = false var isUpdatingOrientationLayout = false
var hitTest: ((CGPoint, UIEvent?) -> UIView?)? var hitTest: ((CGPoint, UIEvent?) -> UIView?)?
var invalidateDeferScreenEdgeGesture: (() -> Void)? var invalidateDeferScreenEdgeGesture: (() -> Void)?
@ -398,8 +398,8 @@ public class Window1 {
self?.layoutSubviews() self?.layoutSubviews()
} }
self.hostView.updateToInterfaceOrientation = { [weak self] in self.hostView.updateToInterfaceOrientation = { [weak self] orientation in
self?.updateToInterfaceOrientation() self?.updateToInterfaceOrientation(orientation)
} }
self.hostView.hitTest = { [weak self] point, event in self.hostView.hitTest = { [weak self] point, event in
@ -844,12 +844,19 @@ public class Window1 {
var postUpdateToInterfaceOrientationBlocks: [() -> Void] = [] var postUpdateToInterfaceOrientationBlocks: [() -> Void] = []
private func updateToInterfaceOrientation() { private func updateToInterfaceOrientation(_ orientation: UIInterfaceOrientation) {
let blocks = self.postUpdateToInterfaceOrientationBlocks let blocks = self.postUpdateToInterfaceOrientationBlocks
self.postUpdateToInterfaceOrientationBlocks = [] self.postUpdateToInterfaceOrientationBlocks = []
for f in blocks { for f in blocks {
f() f()
} }
self._rootController?.updateToInterfaceOrientation(orientation)
self.presentationContext.updateToInterfaceOrientation(orientation)
self.overlayPresentationContext.updateToInterfaceOrientation(orientation)
for controller in self.topLevelOverlayControllers {
controller.updateToInterfaceOrientation(orientation)
}
} }
public func addPostUpdateToInterfaceOrientationBlock(f: @escaping () -> Void) { public func addPostUpdateToInterfaceOrientationBlock(f: @escaping () -> Void) {