mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-17 11:50:56 +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 navigationController: NavigationController?
|
||||||
|
|
||||||
|
let passthroughTouches: Bool = true
|
||||||
|
|
||||||
init(controller: ViewController, sourceNode: ASDisplayNode?, navigationController: NavigationController?) {
|
init(controller: ViewController, sourceNode: ASDisplayNode?, navigationController: NavigationController?) {
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.sourceNode = sourceNode
|
self.sourceNode = sourceNode
|
||||||
@ -91,6 +93,9 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func animatedIn() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ChatListControllerImpl: TelegramBaseController, ChatListController, UIViewControllerPreviewingDelegate {
|
public class ChatListControllerImpl: TelegramBaseController, ChatListController, UIViewControllerPreviewingDelegate {
|
||||||
|
|||||||
@ -33,6 +33,8 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
|||||||
|
|
||||||
let navigationController: NavigationController? = nil
|
let navigationController: NavigationController? = nil
|
||||||
|
|
||||||
|
let passthroughTouches: Bool = true
|
||||||
|
|
||||||
init(controller: ViewController, sourceNode: ASDisplayNode?) {
|
init(controller: ViewController, sourceNode: ASDisplayNode?) {
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.sourceNode = sourceNode
|
self.sourceNode = sourceNode
|
||||||
@ -48,6 +50,9 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func animatedIn() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class ContactsControllerNode: ASDisplayNode {
|
final class ContactsControllerNode: ASDisplayNode {
|
||||||
|
|||||||
@ -211,7 +211,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
|||||||
if strongSelf.didCompleteAnimationIn {
|
if strongSelf.didCompleteAnimationIn {
|
||||||
if !strongSelf.didMoveFromInitialGesturePoint {
|
if !strongSelf.didMoveFromInitialGesturePoint {
|
||||||
let distance = abs(localPoint.y - initialPoint.y)
|
let distance = abs(localPoint.y - initialPoint.y)
|
||||||
if distance > 4.0 {
|
if distance > 12.0 {
|
||||||
strongSelf.didMoveFromInitialGesturePoint = true
|
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)
|
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)
|
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 {
|
if let contentNode = self.contentContainerNode.contentNode, case let .controller(controller) = contentNode {
|
||||||
let snapshotView: UIView? = nil// controller.sourceNode.view.snapshotContentTree()
|
let snapshotView: UIView? = nil// controller.sourceNode.view.snapshotContentTree()
|
||||||
@ -1099,7 +1106,16 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case let .controller(contentParentNode):
|
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)
|
self.originalProjectedContentViewFrame = (projectedFrame, projectedFrame)
|
||||||
|
|
||||||
if let originalProjectedContentViewFrame = self.originalProjectedContentViewFrame {
|
if let originalProjectedContentViewFrame = self.originalProjectedContentViewFrame {
|
||||||
@ -1149,8 +1165,9 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
|||||||
var contentHeight: CGFloat
|
var contentHeight: CGFloat
|
||||||
if case .compact = layout.metrics.widthClass {
|
if case .compact = layout.metrics.widthClass {
|
||||||
if layout.size.width < layout.size.height {
|
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)
|
let sideInset = floor((layout.size.width - max(contentSize.width, actionsSize.width)) / 2.0)
|
||||||
originalContentFrame = CGRect(origin: CGPoint(x: actionsSideInset, y: originalActionsFrame.minY - contentActionsSpacing - contentSize.height), size: contentSize)
|
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 {
|
if originalContentFrame.minY < topEdge {
|
||||||
let requiredOffset = topEdge - originalContentFrame.minY
|
let requiredOffset = topEdge - originalContentFrame.minY
|
||||||
let availableOffset = max(0.0, layout.size.height - layout.intrinsicInsets.bottom - actionsBottomInset - originalActionsFrame.maxY)
|
let availableOffset = max(0.0, layout.size.height - layout.intrinsicInsets.bottom - actionsBottomInset - originalActionsFrame.maxY)
|
||||||
@ -1271,6 +1288,14 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case let .controller(controller):
|
case let .controller(controller):
|
||||||
|
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)
|
let controllerPoint = self.view.convert(point, to: controller.controller.view)
|
||||||
if let result = controller.controller.view.hitTest(controllerPoint, with: event) {
|
if let result = controller.controller.view.hitTest(controllerPoint, with: event) {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@ -1280,6 +1305,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if self.actionsContainerNode.frame.contains(mappedPoint) {
|
if self.actionsContainerNode.frame.contains(mappedPoint) {
|
||||||
return self.actionsContainerNode.hitTest(self.view.convert(point, to: self.actionsContainerNode.view), with: event)
|
return self.actionsContainerNode.hitTest(self.view.convert(point, to: self.actionsContainerNode.view), with: event)
|
||||||
@ -1325,8 +1351,11 @@ public protocol ContextExtractedContentSource: class {
|
|||||||
public protocol ContextControllerContentSource: class {
|
public protocol ContextControllerContentSource: class {
|
||||||
var controller: ViewController { get }
|
var controller: ViewController { get }
|
||||||
var navigationController: NavigationController? { get }
|
var navigationController: NavigationController? { get }
|
||||||
|
var passthroughTouches: Bool { get }
|
||||||
|
|
||||||
func transitionInfo() -> ContextControllerTakeControllerInfo?
|
func transitionInfo() -> ContextControllerTakeControllerInfo?
|
||||||
|
|
||||||
|
func animatedIn()
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ContextContentSource {
|
public enum ContextContentSource {
|
||||||
|
|||||||
@ -11,6 +11,8 @@ public final class ContextControllerSourceNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public var activated: ((ContextGesture) -> Void)?
|
public var activated: ((ContextGesture) -> Void)?
|
||||||
|
public var shouldBegin: ((CGPoint) -> Bool)?
|
||||||
|
public var customActivationProgress: ((CGFloat, ContextGestureTransition) -> Void)?
|
||||||
|
|
||||||
override public func didLoad() {
|
override public func didLoad() {
|
||||||
super.didLoad()
|
super.didLoad()
|
||||||
@ -19,10 +21,20 @@ public final class ContextControllerSourceNode: ASDisplayNode {
|
|||||||
self.contextGesture = contextGesture
|
self.contextGesture = contextGesture
|
||||||
self.view.addGestureRecognizer(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
|
contextGesture.activationProgress = { [weak self] progress, update in
|
||||||
guard let strongSelf = self, !strongSelf.bounds.width.isZero else {
|
guard let strongSelf = self, !strongSelf.bounds.width.isZero else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if let customActivationProgress = strongSelf.customActivationProgress {
|
||||||
|
customActivationProgress(progress, update)
|
||||||
|
} else {
|
||||||
let minScale: CGFloat = (strongSelf.bounds.width - 10.0) / strongSelf.bounds.width
|
let minScale: CGFloat = (strongSelf.bounds.width - 10.0) / strongSelf.bounds.width
|
||||||
let currentScale = 1.0 * (1.0 - progress) + minScale * progress
|
let currentScale = 1.0 * (1.0 - progress) + minScale * progress
|
||||||
switch update {
|
switch update {
|
||||||
@ -36,6 +48,7 @@ public final class ContextControllerSourceNode: ASDisplayNode {
|
|||||||
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)
|
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
|
contextGesture.activated = { [weak self] gesture in
|
||||||
if let activated = self?.activated {
|
if let activated = self?.activated {
|
||||||
activated(gesture)
|
activated(gesture)
|
||||||
|
|||||||
@ -56,6 +56,7 @@ public final class ContextGesture: UIGestureRecognizer, UIGestureRecognizerDeleg
|
|||||||
private var animator: DisplayLinkAnimator?
|
private var animator: DisplayLinkAnimator?
|
||||||
private var isValidated: Bool = false
|
private var isValidated: Bool = false
|
||||||
|
|
||||||
|
public var shouldBegin: ((CGPoint) -> Bool)?
|
||||||
public var activationProgress: ((CGFloat, ContextGestureTransition) -> Void)?
|
public var activationProgress: ((CGFloat, ContextGestureTransition) -> Void)?
|
||||||
public var activated: ((ContextGesture) -> Void)?
|
public var activated: ((ContextGesture) -> Void)?
|
||||||
public var externalUpdated: ((UIView?, CGPoint) -> 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) {
|
override public func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
|
||||||
super.touchesBegan(touches, with: event)
|
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 {
|
if self.delayTimer == nil {
|
||||||
let delayTimer = Timer(timeInterval: beginDelay, target: TimerTargetWrapper { [weak self] in
|
let delayTimer = Timer(timeInterval: beginDelay, target: TimerTargetWrapper { [weak self] in
|
||||||
guard let strongSelf = self, let _ = strongSelf.delayTimer else {
|
guard let strongSelf = self, let _ = strongSelf.delayTimer else {
|
||||||
|
|||||||
@ -220,6 +220,8 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
|||||||
|
|
||||||
let navigationController: NavigationController? = nil
|
let navigationController: NavigationController? = nil
|
||||||
|
|
||||||
|
let passthroughTouches: Bool = true
|
||||||
|
|
||||||
init(controller: ViewController, sourceNode: ASDisplayNode?) {
|
init(controller: ViewController, sourceNode: ASDisplayNode?) {
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.sourceNode = sourceNode
|
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 navigationController: NavigationController? = nil
|
||||||
|
|
||||||
|
let passthroughTouches: Bool = false
|
||||||
|
|
||||||
init(controller: ViewController, sourceNode: ASDisplayNode?) {
|
init(controller: ViewController, sourceNode: ASDisplayNode?) {
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.sourceNode = sourceNode
|
self.sourceNode = sourceNode
|
||||||
@ -61,6 +63,9 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func animatedIn() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private indirect enum SettingsEntryTag: Equatable, ItemListItemTag {
|
private indirect enum SettingsEntryTag: Equatable, ItemListItemTag {
|
||||||
|
|||||||
@ -22,6 +22,8 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
|||||||
|
|
||||||
let navigationController: NavigationController? = nil
|
let navigationController: NavigationController? = nil
|
||||||
|
|
||||||
|
let passthroughTouches: Bool = false
|
||||||
|
|
||||||
init(controller: ViewController, sourceNode: ASDisplayNode?) {
|
init(controller: ViewController, sourceNode: ASDisplayNode?) {
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.sourceNode = sourceNode
|
self.sourceNode = sourceNode
|
||||||
@ -37,6 +39,9 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func animatedIn() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func themeDisplayName(strings: PresentationStrings, reference: PresentationThemeReference) -> String {
|
func themeDisplayName(strings: PresentationStrings, reference: PresentationThemeReference) -> String {
|
||||||
|
|||||||
@ -8187,6 +8187,8 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
|||||||
|
|
||||||
let navigationController: NavigationController? = nil
|
let navigationController: NavigationController? = nil
|
||||||
|
|
||||||
|
let passthroughTouches: Bool = false
|
||||||
|
|
||||||
init(controller: ViewController, sourceNode: ASDisplayNode?) {
|
init(controller: ViewController, sourceNode: ASDisplayNode?) {
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.sourceNode = sourceNode
|
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 navigationController: NavigationController? = nil
|
||||||
|
|
||||||
|
let passthroughTouches: Bool = false
|
||||||
|
|
||||||
init(controller: ViewController, sourceNode: ASDisplayNode?) {
|
init(controller: ViewController, sourceNode: ASDisplayNode?) {
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.sourceNode = sourceNode
|
self.sourceNode = sourceNode
|
||||||
@ -938,4 +940,7 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func animatedIn() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user