mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
188 lines
6.9 KiB
Swift
188 lines
6.9 KiB
Swift
import Foundation
|
|
import AsyncDisplayKit
|
|
|
|
public class WindowRootViewController: UIViewController {
|
|
public override func preferredStatusBarStyle() -> UIStatusBarStyle {
|
|
return .Default
|
|
}
|
|
|
|
public override func prefersStatusBarHidden() -> Bool {
|
|
return false
|
|
}
|
|
}
|
|
|
|
public struct ViewControllerLayout: Equatable {
|
|
public let size: CGSize
|
|
public let insets: UIEdgeInsets
|
|
public let inputViewHeight: CGFloat
|
|
public let statusBarHeight: CGFloat
|
|
}
|
|
|
|
public protocol WindowContentController {
|
|
func setParentLayout(layout: ViewControllerLayout, duration: NSTimeInterval, curve: UInt)
|
|
var view: UIView! { get }
|
|
}
|
|
|
|
public func animateRotation(view: UIView?, toFrame: CGRect, duration: NSTimeInterval) {
|
|
if let view = view {
|
|
UIView.animateWithDuration(duration, animations: { () -> Void in
|
|
view.frame = toFrame
|
|
})
|
|
}
|
|
}
|
|
|
|
public func animateRotation(view: ASDisplayNode?, toFrame: CGRect, duration: NSTimeInterval) {
|
|
if let view = view {
|
|
CALayer.beginRecordingChanges()
|
|
UIView.animateWithDuration(duration, animations: { () -> Void in
|
|
view.frame = toFrame
|
|
})
|
|
view.layout()
|
|
let states = CALayer.endRecordingChanges() as! [CALayerAnimation]
|
|
let k = Float(UIView.animationDurationFactor())
|
|
var speed: Float = 1.0
|
|
if k != 0 && k != 1 {
|
|
speed = Float(1.0) / k
|
|
}
|
|
for state in states {
|
|
if let layer = state.layer {
|
|
if !CGRectEqualToRect(state.startBounds, state.endBounds) {
|
|
let boundsAnimation = CABasicAnimation(keyPath: "bounds")
|
|
boundsAnimation.fromValue = NSValue(CGRect: state.startBounds)
|
|
boundsAnimation.toValue = NSValue(CGRect: state.endBounds)
|
|
boundsAnimation.duration = duration
|
|
boundsAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
|
|
boundsAnimation.removedOnCompletion = true
|
|
boundsAnimation.fillMode = kCAFillModeForwards
|
|
boundsAnimation.speed = speed
|
|
layer.addAnimation(boundsAnimation, forKey: "_rotationBounds")
|
|
}
|
|
|
|
if !CGPointEqualToPoint(state.startPosition, state.endPosition) {
|
|
let positionAnimation = CABasicAnimation(keyPath: "position")
|
|
positionAnimation.fromValue = NSValue(CGPoint: state.startPosition)
|
|
positionAnimation.toValue = NSValue(CGPoint: state.endPosition)
|
|
positionAnimation.duration = duration
|
|
positionAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
|
|
positionAnimation.removedOnCompletion = true
|
|
positionAnimation.fillMode = kCAFillModeForwards
|
|
positionAnimation.speed = speed
|
|
layer.addAnimation(positionAnimation, forKey: "_rotationPosition")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public class Window: UIWindow {
|
|
private let statusBarManager: StatusBarManager
|
|
|
|
private var updateViewSizeOnLayout: (Bool, NSTimeInterval) = (false, 0.0)
|
|
public var isUpdatingOrientationLayout = false
|
|
|
|
private let orientationChangeDuration: NSTimeInterval = {
|
|
UIDevice.currentDevice().userInterfaceIdiom == .Pad ? 0.4 : 0.3
|
|
}()
|
|
|
|
public convenience init() {
|
|
self.init(frame: UIScreen.mainScreen().bounds)
|
|
}
|
|
|
|
public override init(frame: CGRect) {
|
|
self.statusBarManager = StatusBarManager()
|
|
|
|
super.init(frame: frame)
|
|
|
|
super.rootViewController = WindowRootViewController()
|
|
}
|
|
|
|
public required init(coder aDecoder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
public override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
|
|
return self.viewController?.view.hitTest(point, withEvent: event)
|
|
}
|
|
|
|
public override var frame: CGRect {
|
|
get {
|
|
return super.frame
|
|
}
|
|
set(value) {
|
|
let sizeUpdated = super.frame.size != value.size
|
|
super.frame = value
|
|
|
|
if sizeUpdated {
|
|
self.updateViewSizeOnLayout = (true, self.isRotating() ? self.orientationChangeDuration : 0.0)
|
|
self.setNeedsLayout()
|
|
}
|
|
}
|
|
}
|
|
|
|
public override var bounds: CGRect {
|
|
get {
|
|
return super.frame
|
|
}
|
|
set(value) {
|
|
let sizeUpdated = super.bounds.size != value.size
|
|
super.bounds = value
|
|
|
|
if sizeUpdated {
|
|
self.updateViewSizeOnLayout = (true, self.isRotating() ? self.orientationChangeDuration : 0.0)
|
|
self.setNeedsLayout()
|
|
}
|
|
}
|
|
}
|
|
|
|
private var _rootViewController: WindowContentController?
|
|
public var viewController: WindowContentController? {
|
|
get {
|
|
return _rootViewController
|
|
}
|
|
set(value) {
|
|
self._rootViewController?.view.removeFromSuperview()
|
|
self._rootViewController = value
|
|
self._rootViewController?.view.frame = self.bounds
|
|
self._rootViewController?.setParentLayout(ViewControllerLayout(size: self.bounds.size, insets: UIEdgeInsets(), inputViewHeight: 0.0, statusBarHeight: 0.0), duration: 0.0, curve: 0)
|
|
|
|
if let view = self._rootViewController?.view {
|
|
self.addSubview(view)
|
|
}
|
|
|
|
self.updateStatusBars()
|
|
}
|
|
}
|
|
|
|
override public func layoutSubviews() {
|
|
super.layoutSubviews()
|
|
|
|
if self.updateViewSizeOnLayout.0 {
|
|
self.updateViewSizeOnLayout.0 = false
|
|
|
|
self._rootViewController?.setParentLayout(ViewControllerLayout(size: self.bounds.size, insets: UIEdgeInsets(), inputViewHeight: 0.0, statusBarHeight: 0.0), duration: updateViewSizeOnLayout.1, curve: 0)
|
|
}
|
|
}
|
|
|
|
var postUpdateToInterfaceOrientationBlocks: [Void -> Void] = []
|
|
|
|
override public func _updateToInterfaceOrientation(arg1: Int32, duration arg2: Double, force arg3: Bool) {
|
|
self.isUpdatingOrientationLayout = true
|
|
super._updateToInterfaceOrientation(arg1, duration: arg2, force: arg3)
|
|
self.isUpdatingOrientationLayout = false
|
|
|
|
let blocks = self.postUpdateToInterfaceOrientationBlocks
|
|
self.postUpdateToInterfaceOrientationBlocks = []
|
|
for f in blocks {
|
|
f()
|
|
}
|
|
}
|
|
|
|
public func addPostUpdateToInterfaceOrientationBlock(f: Void -> Void) {
|
|
postUpdateToInterfaceOrientationBlocks.append(f)
|
|
}
|
|
|
|
func updateStatusBars() {
|
|
self.statusBarManager.surfaces = (self._rootViewController as? StatusBarSurfaceProvider)?.statusBarSurfaces() ?? []
|
|
}
|
|
}
|