mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 03:20:48 +00:00
Update ContextUI API
This commit is contained in:
parent
70000b0027
commit
cb939af2c0
@ -75,6 +75,8 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
||||
|
||||
let navigationController: NavigationController?
|
||||
|
||||
let passthroughTouches: Bool = true
|
||||
|
||||
init(controller: ViewController, sourceNode: ASDisplayNode?, navigationController: NavigationController?) {
|
||||
self.controller = controller
|
||||
self.sourceNode = sourceNode
|
||||
@ -91,6 +93,9 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func animatedIn() {
|
||||
}
|
||||
}
|
||||
|
||||
public class ChatListControllerImpl: TelegramBaseController, ChatListController, UIViewControllerPreviewingDelegate {
|
||||
|
@ -33,6 +33,8 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
||||
|
||||
let navigationController: NavigationController? = nil
|
||||
|
||||
let passthroughTouches: Bool = true
|
||||
|
||||
init(controller: ViewController, sourceNode: ASDisplayNode?) {
|
||||
self.controller = controller
|
||||
self.sourceNode = sourceNode
|
||||
@ -48,6 +50,9 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func animatedIn() {
|
||||
}
|
||||
}
|
||||
|
||||
final class ContactsControllerNode: ASDisplayNode {
|
||||
|
@ -211,7 +211,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
||||
if strongSelf.didCompleteAnimationIn {
|
||||
if !strongSelf.didMoveFromInitialGesturePoint {
|
||||
let distance = abs(localPoint.y - initialPoint.y)
|
||||
if distance > 4.0 {
|
||||
if distance > 12.0 {
|
||||
strongSelf.didMoveFromInitialGesturePoint = true
|
||||
}
|
||||
}
|
||||
@ -581,6 +581,13 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
||||
|
||||
self.contentContainerNode.layer.animateSpring(from: min(localSourceFrame.width / self.contentContainerNode.frame.width, localSourceFrame.height / self.contentContainerNode.frame.height) as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: springDuration, initialVelocity: 0.0, damping: springDamping)
|
||||
|
||||
switch self.source {
|
||||
case let .controller(controller):
|
||||
controller.animatedIn()
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
let contentContainerOffset = CGPoint(x: localSourceFrame.center.x - self.contentContainerNode.frame.center.x, y: localSourceFrame.center.y - self.contentContainerNode.frame.center.y)
|
||||
if let contentNode = self.contentContainerNode.contentNode, case let .controller(controller) = contentNode {
|
||||
let snapshotView: UIView? = nil// controller.sourceNode.view.snapshotContentTree()
|
||||
@ -1099,7 +1106,16 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
||||
}
|
||||
}
|
||||
case let .controller(contentParentNode):
|
||||
let projectedFrame = convertFrame(contentParentNode.sourceNode.bounds, from: contentParentNode.sourceNode.view, to: self.view)
|
||||
var projectedFrame: CGRect = convertFrame(contentParentNode.sourceNode.bounds, from: contentParentNode.sourceNode.view, to: self.view)
|
||||
switch self.source {
|
||||
case let .controller(source):
|
||||
let transitionInfo = source.transitionInfo()
|
||||
if let (sourceNode, sourceRect) = transitionInfo?.sourceNode() {
|
||||
projectedFrame = convertFrame(sourceRect, from: sourceNode.view, to: self.view)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
self.originalProjectedContentViewFrame = (projectedFrame, projectedFrame)
|
||||
|
||||
if let originalProjectedContentViewFrame = self.originalProjectedContentViewFrame {
|
||||
@ -1149,8 +1165,9 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
||||
var contentHeight: CGFloat
|
||||
if case .compact = layout.metrics.widthClass {
|
||||
if layout.size.width < layout.size.height {
|
||||
originalActionsFrame = CGRect(origin: CGPoint(x: actionsSideInset, y: min(maximumActionsFrameOrigin, floor((layout.size.height - contentActionsSpacing - contentSize.height) / 2.0) + contentSize.height + contentActionsSpacing)), size: actionsSize)
|
||||
originalContentFrame = CGRect(origin: CGPoint(x: actionsSideInset, y: originalActionsFrame.minY - contentActionsSpacing - contentSize.height), size: contentSize)
|
||||
let sideInset = floor((layout.size.width - max(contentSize.width, actionsSize.width)) / 2.0)
|
||||
originalActionsFrame = CGRect(origin: CGPoint(x: sideInset, y: min(maximumActionsFrameOrigin, floor((layout.size.height - contentActionsSpacing - contentSize.height) / 2.0) + contentSize.height + contentActionsSpacing)), size: actionsSize)
|
||||
originalContentFrame = CGRect(origin: CGPoint(x: sideInset, y: originalActionsFrame.minY - contentActionsSpacing - contentSize.height), size: contentSize)
|
||||
if originalContentFrame.minY < topEdge {
|
||||
let requiredOffset = topEdge - originalContentFrame.minY
|
||||
let availableOffset = max(0.0, layout.size.height - layout.intrinsicInsets.bottom - actionsBottomInset - originalActionsFrame.maxY)
|
||||
@ -1271,12 +1288,21 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
||||
}
|
||||
}
|
||||
case let .controller(controller):
|
||||
let controllerPoint = self.view.convert(point, to: controller.controller.view)
|
||||
if let result = controller.controller.view.hitTest(controllerPoint, with: event) {
|
||||
#if DEBUG
|
||||
//return controller.view
|
||||
#endif
|
||||
return result
|
||||
var passthrough = false
|
||||
switch self.source {
|
||||
case let .controller(controllerSource):
|
||||
passthrough = controllerSource.passthroughTouches
|
||||
default:
|
||||
break
|
||||
}
|
||||
if passthrough {
|
||||
let controllerPoint = self.view.convert(point, to: controller.controller.view)
|
||||
if let result = controller.controller.view.hitTest(controllerPoint, with: event) {
|
||||
#if DEBUG
|
||||
//return controller.view
|
||||
#endif
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1325,8 +1351,11 @@ public protocol ContextExtractedContentSource: class {
|
||||
public protocol ContextControllerContentSource: class {
|
||||
var controller: ViewController { get }
|
||||
var navigationController: NavigationController? { get }
|
||||
var passthroughTouches: Bool { get }
|
||||
|
||||
func transitionInfo() -> ContextControllerTakeControllerInfo?
|
||||
|
||||
func animatedIn()
|
||||
}
|
||||
|
||||
public enum ContextContentSource {
|
||||
|
@ -11,6 +11,8 @@ public final class ContextControllerSourceNode: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
public var activated: ((ContextGesture) -> Void)?
|
||||
public var shouldBegin: ((CGPoint) -> Bool)?
|
||||
public var customActivationProgress: ((CGFloat, ContextGestureTransition) -> Void)?
|
||||
|
||||
override public func didLoad() {
|
||||
super.didLoad()
|
||||
@ -19,21 +21,32 @@ public final class ContextControllerSourceNode: ASDisplayNode {
|
||||
self.contextGesture = contextGesture
|
||||
self.view.addGestureRecognizer(contextGesture)
|
||||
|
||||
contextGesture.shouldBegin = { [weak self] point in
|
||||
guard let strongSelf = self, !strongSelf.bounds.width.isZero else {
|
||||
return false
|
||||
}
|
||||
return strongSelf.shouldBegin?(point) ?? false
|
||||
}
|
||||
|
||||
contextGesture.activationProgress = { [weak self] progress, update in
|
||||
guard let strongSelf = self, !strongSelf.bounds.width.isZero else {
|
||||
return
|
||||
}
|
||||
let minScale: CGFloat = (strongSelf.bounds.width - 10.0) / strongSelf.bounds.width
|
||||
let currentScale = 1.0 * (1.0 - progress) + minScale * progress
|
||||
switch update {
|
||||
case .update:
|
||||
strongSelf.layer.sublayerTransform = CATransform3DMakeScale(currentScale, currentScale, 1.0)
|
||||
case .begin:
|
||||
strongSelf.layer.sublayerTransform = CATransform3DMakeScale(currentScale, currentScale, 1.0)
|
||||
case let .ended(previousProgress):
|
||||
let previousScale = 1.0 * (1.0 - previousProgress) + minScale * previousProgress
|
||||
strongSelf.layer.sublayerTransform = CATransform3DMakeScale(currentScale, currentScale, 1.0)
|
||||
strongSelf.layer.animateSpring(from: previousScale as NSNumber, to: currentScale as NSNumber, keyPath: "sublayerTransform.scale", duration: 0.5, delay: 0.0, initialVelocity: 0.0, damping: 90.0)
|
||||
if let customActivationProgress = strongSelf.customActivationProgress {
|
||||
customActivationProgress(progress, update)
|
||||
} else {
|
||||
let minScale: CGFloat = (strongSelf.bounds.width - 10.0) / strongSelf.bounds.width
|
||||
let currentScale = 1.0 * (1.0 - progress) + minScale * progress
|
||||
switch update {
|
||||
case .update:
|
||||
strongSelf.layer.sublayerTransform = CATransform3DMakeScale(currentScale, currentScale, 1.0)
|
||||
case .begin:
|
||||
strongSelf.layer.sublayerTransform = CATransform3DMakeScale(currentScale, currentScale, 1.0)
|
||||
case let .ended(previousProgress):
|
||||
let previousScale = 1.0 * (1.0 - previousProgress) + minScale * previousProgress
|
||||
strongSelf.layer.sublayerTransform = CATransform3DMakeScale(currentScale, currentScale, 1.0)
|
||||
strongSelf.layer.animateSpring(from: previousScale as NSNumber, to: currentScale as NSNumber, keyPath: "sublayerTransform.scale", duration: 0.5, delay: 0.0, initialVelocity: 0.0, damping: 90.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
contextGesture.activated = { [weak self] gesture in
|
||||
|
@ -56,6 +56,7 @@ public final class ContextGesture: UIGestureRecognizer, UIGestureRecognizerDeleg
|
||||
private var animator: DisplayLinkAnimator?
|
||||
private var isValidated: Bool = false
|
||||
|
||||
public var shouldBegin: ((CGPoint) -> Bool)?
|
||||
public var activationProgress: ((CGFloat, ContextGestureTransition) -> Void)?
|
||||
public var activated: ((ContextGesture) -> Void)?
|
||||
public var externalUpdated: ((UIView?, CGPoint) -> Void)?
|
||||
@ -92,6 +93,13 @@ public final class ContextGesture: UIGestureRecognizer, UIGestureRecognizerDeleg
|
||||
override public func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
|
||||
super.touchesBegan(touches, with: event)
|
||||
|
||||
if let shouldBegin = self.shouldBegin, let touch = touches.first {
|
||||
if !shouldBegin(touch.location(in: self.view)) {
|
||||
self.state = .failed
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if self.delayTimer == nil {
|
||||
let delayTimer = Timer(timeInterval: beginDelay, target: TimerTargetWrapper { [weak self] in
|
||||
guard let strongSelf = self, let _ = strongSelf.delayTimer else {
|
||||
|
@ -220,6 +220,8 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
||||
|
||||
let navigationController: NavigationController? = nil
|
||||
|
||||
let passthroughTouches: Bool = true
|
||||
|
||||
init(controller: ViewController, sourceNode: ASDisplayNode?) {
|
||||
self.controller = controller
|
||||
self.sourceNode = sourceNode
|
||||
@ -235,4 +237,7 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func animatedIn() {
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,8 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
||||
|
||||
let navigationController: NavigationController? = nil
|
||||
|
||||
let passthroughTouches: Bool = false
|
||||
|
||||
init(controller: ViewController, sourceNode: ASDisplayNode?) {
|
||||
self.controller = controller
|
||||
self.sourceNode = sourceNode
|
||||
@ -61,6 +63,9 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func animatedIn() {
|
||||
}
|
||||
}
|
||||
|
||||
private indirect enum SettingsEntryTag: Equatable, ItemListItemTag {
|
||||
|
@ -22,6 +22,8 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
||||
|
||||
let navigationController: NavigationController? = nil
|
||||
|
||||
let passthroughTouches: Bool = false
|
||||
|
||||
init(controller: ViewController, sourceNode: ASDisplayNode?) {
|
||||
self.controller = controller
|
||||
self.sourceNode = sourceNode
|
||||
@ -37,6 +39,9 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func animatedIn() {
|
||||
}
|
||||
}
|
||||
|
||||
func themeDisplayName(strings: PresentationStrings, reference: PresentationThemeReference) -> String {
|
||||
|
@ -8187,6 +8187,8 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
||||
|
||||
let navigationController: NavigationController? = nil
|
||||
|
||||
let passthroughTouches: Bool = false
|
||||
|
||||
init(controller: ViewController, sourceNode: ASDisplayNode?) {
|
||||
self.controller = controller
|
||||
self.sourceNode = sourceNode
|
||||
@ -8202,4 +8204,7 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func animatedIn() {
|
||||
}
|
||||
}
|
||||
|
@ -923,6 +923,8 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
||||
|
||||
let navigationController: NavigationController? = nil
|
||||
|
||||
let passthroughTouches: Bool = false
|
||||
|
||||
init(controller: ViewController, sourceNode: ASDisplayNode?) {
|
||||
self.controller = controller
|
||||
self.sourceNode = sourceNode
|
||||
@ -938,4 +940,7 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func animatedIn() {
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user