ContextController
protocol
ContextControllerProtocol
1
2
3
4
5
6
7
8
9
| var useComplexItemsTransitionAnimation: Bool { get set }
var immediateItemsTransitionAnimation: Bool { get set }
func getActionsMinHeight() -> ContextController.ActionsHeight?
func setItems(_ items: Signal<ContextController.Items, NoError>, minHeight: ContextController.ActionsHeight?)
func setItems(_ items: Signal<ContextController.Items, NoError>, minHeight: ContextController.ActionsHeight?, previousActionsTransition: ContextController.PreviousActionsTransition)
func pushItems(items: Signal<ContextController.Items, NoError>)
func popItems()
func dismiss(completion: (() -> Void)?)
|
enum
ContextMenuActionItemTextLayout
1
2
3
| case singleLine
case twoLinesMax
case secondLineWithValue(String)
|
enum
ContextMenuActionItemTextColor
1
2
3
| case primary
case destructive
case disabled
|
enum
ContextMenuActionResult
1
2
3
| case `default`
case dismissWithoutContent
case custom(ContainedViewLayoutTransition)
|
enum
ContextMenuActionItemFont
1
2
| case regular
case custom(UIFont)
|
struct
ContextMenuActionItemIconSource
1
2
| public let size: CGSize
public let signal: Signal<UIImage?, NoError>
|
enum
ContextMenuActionBadgeColor
1
2
| case accent
case inactive
|
struct
ContextMenuActionBadge
1
2
| public var value: String
public var color: ContextMenuActionBadgeColor
|
class
ContextMenuActionItem
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| public final class Action {
public let controller: ContextControllerProtocol
public let dismissWithResult: (ContextMenuActionResult) -> Void
public let updateAction: (AnyHashable, ContextMenuActionItem) -> Void
init(controller: ContextControllerProtocol, dismissWithResult: @escaping (ContextMenuActionResult) -> Void, updateAction: @escaping (AnyHashable, ContextMenuActionItem) -> Void) {
self.controller = controller
self.dismissWithResult = dismissWithResult
self.updateAction = updateAction
}
}
// the id
public let id: AnyHashable?
// text
public let text: String
public let textColor: ContextMenuActionItemTextColor
public let textFont: ContextMenuActionItemFont
public let textLayout: ContextMenuActionItemTextLayout
// badge
public let badge: ContextMenuActionBadge?
// icon
public let icon: (PresentationTheme) -> UIImage?
public let iconSource: ContextMenuActionItemIconSource?
// action
public let action: ((Action) -> Void)?
|
protocol
ContextMenuCustomNode
1
2
3
4
5
6
7
8
9
10
11
12
| // update layout
func updateLayout(constrainedWidth: CGFloat, constrainedHeight: CGFloat) -> (CGSize, (CGSize, ContainedViewLayoutTransition) -> Void)
// update theme
func updateTheme(presentationData: PresentationData)
// highlight
func canBeHighlighted() -> Bool
func updateIsHighlighted(isHighlighted: Bool)
// perform action
func performAction()
|
protocol
ContextMenuCustomItem
1
| func node(presentationData: PresentationData, getController: @escaping () -> ContextControllerProtocol?, actionSelected: @escaping (ContextMenuActionResult) -> Void) -> ContextMenuCustomNode
|
enum
ContextMenuItem
1
2
3
| case action(ContextMenuActionItem)
case custom(ContextMenuCustomItem, Bool)
case separator
|
Convert Frame
1
2
3
4
5
6
7
8
9
| func convertFrame(_ frame: CGRect, from fromView: UIView, to toView: UIView) -> CGRect {
let sourceWindowFrame = fromView.convert(frame, to: nil)
var targetWindowFrame = toView.convert(sourceWindowFrame, from: nil)
if let fromWindow = fromView.window, let toWindow = toView.window {
targetWindowFrame.origin.x += toWindow.bounds.width - fromWindow.bounds.width
}
return targetWindowFrame
}
|
ContextContentSource
class
ContextControllerReferenceViewInfo
1
2
3
4
| public let referenceView: UIView
public let contentAreaInScreenSpace: CGRect
public let insets: UIEdgeInsets
public let customPosition: CGPoint?
|
protocol
ContextReferenceContentSource
1
2
3
| var shouldBeDismissed: Signal<Bool, NoError> { get }
func transitionInfo() -> ContextControllerReferenceViewInfo?
|
class
ContextExtractedContentNode
1
2
3
4
5
6
7
8
9
10
| public var customHitTest: ((CGPoint) -> UIView?)?
public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let result = self.view.hitTest(point, with: event)
if result === self.view {
return nil
} else {
return result
}
}
|
class
ContextExtractedContentContainingNode
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
| public let contentNode: ContextExtractedContentNode
public var contentRect: CGRect = CGRect()
// isExtractedToContextPreview
public var isExtractedToContextPreview: Bool = false
public var willUpdateIsExtractedToContextPreview: ((Bool, ContainedViewLayoutTransition) -> Void)?
public var isExtractedToContextPreviewUpdated: ((Bool) -> Void)?
// update rect
public var updateAbsoluteRect: ((CGRect, CGSize) -> Void)?
// apply offset
public var applyAbsoluteOffset: ((CGPoint, ContainedViewLayoutTransitionCurve, Double) -> Void)?
public var applyAbsoluteOffsetSpring: ((CGFloat, Double, CGFloat) -> Void)?
// layout updated
public var layoutUpdated: ((CGSize, ListViewItemUpdateAnimation) -> Void)?
// update distraction free mode
public var updateDistractionFreeMode: ((Bool) -> Void)?
// request dismiss
public var requestDismiss: (() -> Void)?
public override init() {
self.contentNode = ContextExtractedContentNode()
super.init()
self.addSubnode(self.contentNode)
}
public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if self.contentNode.supernode === self {
return self.contentNode.hitTest(self.view.convert(point, to: self.contentNode.view), with: event)
} else {
return nil
}
}
|
class
ContextControllerTakeViewInfo
1
2
3
| public let contentContainingNode: ContextExtractedContentContainingNode
public let contentAreaInScreenSpace: CGRect
public let maskView: UIView?
|
class
ContextControllerPutBackViewInfo
1
2
| public let contentAreaInScreenSpace: CGRect
public let maskView: UIView?
|
protocol
ContextExtractedContentSource
1
2
3
4
5
6
7
8
9
| var centerVertically: Bool { get }
var keepInPlace: Bool { get }
var ignoreContentTouches: Bool { get }
var blurBackground: Bool { get }
var centerActionsHorizontally: Bool { get }
var shouldBeDismissed: Signal<Bool, NoError> { get }
func takeView() -> ContextControllerTakeViewInfo?
func putBack() -> ContextControllerPutBackViewInfo?
|
class
ContextControllerTakeControllerInfo
1
2
| public let contentAreaInScreenSpace: CGRect
public let sourceNode: () -> (ASDisplayNode, CGRect)?
|
protocol
ContextControllerContentSource
1
2
3
4
5
6
| var controller: ViewController { get }
var navigationController: NavigationController? { get }
var passthroughTouches: Bool { get }
func transitionInfo() -> ContextControllerTakeControllerInfo?
func animatedIn()
|
enum
ContextContentSource
1
2
3
| case reference(ContextReferenceContentSource)
case extracted(ContextExtractedContentSource)
case controller(ContextControllerContentSource)
|
ContextControllerNode
enum
ContextControllerPresentationNodeStateTransition
1
2
| case animateIn
case animateOut(result: ContextMenuActionResult, completion: () -> Void)
|
protocol
ContextControllerPresentationNode
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| func replaceItems(items: ContextController.Items, animated: Bool)
func pushItems(items: ContextController.Items)
func popItems()
// update layout
func update(
presentationData: PresentationData,
layout: ContainerViewLayout,
transition: ContainedViewLayoutTransition,
stateTransition: ContextControllerPresentationNodeStateTransition?
)
// animate out to reaction
func animateOutToReaction(value: String, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?,
addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, completion: @escaping () -> Void)
// cancel reaction animation
func cancelReactionAnimation()
// highlight gesture
func highlightGestureMoved(location: CGPoint)
func highlightGestureFinished(performAction: Bool)
// add content offset
func addRelativeContentOffset(_ offset: CGPoint, transition: ContainedViewLayoutTransition)
|
class
ContextControllerNode
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
| private var presentationData: PresentationData
// source
private let source: ContextContentSource
// items
private var items: Signal<ContextController.Items, NoError>
// dismiss
private let beginDismiss: (ContextMenuActionResult) -> Void
private let beganAnimatingOut: () -> Void
private let attemptTransitionControllerIntoNavigation: () -> Void
fileprivate var dismissedForCancel: (() -> Void)?
// controller
private let getController: () -> ContextControllerProtocol?
// gesture
private weak var gesture: ContextGesture?
// ready
private var didSetItemsReady = false
let itemsReady = Promise<Bool>()
let contentReady = Promise<Bool>()
// current items value
private var currentItems: ContextController.Items?
private var currentActionsMinHeight: ContextController.ActionsHeight?
private var validLayout: ContainerViewLayout?
// effect view
private let effectView: UIVisualEffectView
// property animator
private var propertyAnimator: AnyObject?
// displaylink animator
private var displayLinkAnimator: DisplayLinkAnimator?
// dim node
private let dimNode: ASDisplayNode
private let withoutBlurDimNode: ASDisplayNode
// dismiss node
private let dismissNode: ASDisplayNode
private let dismissAccessibilityArea: AccessibilityAreaNode
private var presentationNode: ContextControllerPresentationNode?
private var currentPresentationStateTransition: ContextControllerPresentationNodeStateTransition?
|