ASVisibilityProtocols.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. //
  2. // ASVisibilityProtocols.h
  3. // AsyncDisplayKit
  4. //
  5. // Created by Garrett Moon on 4/27/16.
  6. //
  7. // Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
  8. // This source code is licensed under the BSD-style license found in the
  9. // LICENSE file in the root directory of this source tree. An additional grant
  10. // of patent rights can be found in the PATENTS file in the same directory.
  11. //
  12. #import "ASLayoutRangeType.h"
  13. #import "ASBaseDefines.h"
  14. NS_ASSUME_NONNULL_BEGIN
  15. @class UIViewController;
  16. ASDISPLAYNODE_EXTERN_C_BEGIN
  17. extern ASLayoutRangeMode ASLayoutRangeModeForVisibilityDepth(NSUInteger visibilityDepth);
  18. ASDISPLAYNODE_EXTERN_C_END
  19. /**
  20. * ASVisibilityDepth
  21. *
  22. * @discussion "Visibility Depth" represents the number of user actions required to make an ASDisplayNode or
  23. * ASViewController visibile. AsyncDisplayKit uses this information to intelligently manage memory and focus
  24. * resources where they are most visible to the user.
  25. *
  26. * The ASVisibilityDepth protocol describes how custom view controllers can integrate with this system.
  27. *
  28. * Parent view controllers should also implement @c ASManagesChildVisibilityDepth
  29. *
  30. * @see ASManagesChildVisibilityDepth
  31. */
  32. @protocol ASVisibilityDepth <NSObject>
  33. /**
  34. * Visibility depth
  35. *
  36. * @discussion Represents the number of user actions necessary to reach the view controller. An increased visibility
  37. * depth indicates a higher number of user interactions for the view controller to be visible again. For example,
  38. * an onscreen navigation controller's top view controller should have a visibility depth of 0. The view controller
  39. * one from the top should have a visibility deptch of 1 as should the root view controller in the stack (because
  40. * the user can hold the back button to pop to the root view controller).
  41. *
  42. * Visibility depth is used to automatically adjust ranges on range controllers (and thus free up memory) and can
  43. * be used to reduce memory usage of other items as well.
  44. */
  45. - (NSInteger)visibilityDepth;
  46. /**
  47. * Called when visibility depth changes
  48. *
  49. * @discussion @c visibilityDepthDidChange is called whenever the visibility depth of the represented view controller
  50. * has changed.
  51. *
  52. * If implemented by a view controller container, use this method to notify child view controllers that their view
  53. * depth has changed @see ASNavigationController.m
  54. *
  55. * If implemented on an ASViewController, use this method to reduce or increase the resources that your
  56. * view controller uses. A higher visibility depth view controller should decrease it's resource usage, a lower
  57. * visibility depth controller should pre-warm resources in preperation for a display at 0 depth.
  58. *
  59. * ASViewController implements this method and reduces / increases range mode of supporting nodes (such as ASCollectionNode
  60. * and ASTableNode).
  61. *
  62. * @see visibilityDepth
  63. */
  64. - (void)visibilityDepthDidChange;
  65. @end
  66. /**
  67. * ASManagesChildVisibilityDepth
  68. *
  69. * @discussion A protocol which should be implemented by container view controllers to allow proper
  70. * propagation of visibility depth
  71. *
  72. * @see ASVisibilityDepth
  73. */
  74. @protocol ASManagesChildVisibilityDepth <ASVisibilityDepth>
  75. /**
  76. * @abstract Container view controllers should adopt this protocol to indicate that they will manage their child's
  77. * visibilityDepth. For example, ASNavigationController adopts this protocol and manages its childrens visibility
  78. * depth.
  79. *
  80. * If you adopt this protocol, you *must* also emit visibilityDepthDidChange messages to child view controllers.
  81. *
  82. * @param childViewController Expected to return the visibility depth of the child view controller.
  83. */
  84. - (NSInteger)visibilityDepthOfChildViewController:(UIViewController *)childViewController;
  85. @end
  86. #define ASVisibilitySetVisibilityDepth \
  87. - (void)setVisibilityDepth:(NSUInteger)visibilityDepth \
  88. { \
  89. if (_visibilityDepth == visibilityDepth) { \
  90. return; \
  91. } \
  92. _visibilityDepth = visibilityDepth; \
  93. [self visibilityDepthDidChange]; \
  94. }
  95. #define ASVisibilityDepthImplementation \
  96. - (NSInteger)visibilityDepth \
  97. { \
  98. if (self.parentViewController && _parentManagesVisibilityDepth == NO) { \
  99. _parentManagesVisibilityDepth = [self.parentViewController conformsToProtocol:@protocol(ASManagesChildVisibilityDepth)]; \
  100. } \
  101. \
  102. if (_parentManagesVisibilityDepth) { \
  103. return [(id <ASManagesChildVisibilityDepth>)self.parentViewController visibilityDepthOfChildViewController:self]; \
  104. } \
  105. return _visibilityDepth; \
  106. }
  107. #define ASVisibilityViewDidDisappearImplementation \
  108. - (void)viewDidDisappear:(BOOL)animated \
  109. { \
  110. [super viewDidDisappear:animated]; \
  111. \
  112. if (_parentManagesVisibilityDepth == NO) { \
  113. [self setVisibilityDepth:1]; \
  114. } \
  115. }
  116. #define ASVisibilityViewWillAppear \
  117. - (void)viewWillAppear:(BOOL)animated \
  118. { \
  119. [super viewWillAppear:animated]; \
  120. \
  121. if (_parentManagesVisibilityDepth == NO) { \
  122. [self setVisibilityDepth:0]; \
  123. } \
  124. }
  125. #define ASVisibilityDidMoveToParentViewController \
  126. - (void)didMoveToParentViewController:(UIViewController *)parent \
  127. { \
  128. [super didMoveToParentViewController:parent]; \
  129. _parentManagesVisibilityDepth = NO; \
  130. [self visibilityDepthDidChange]; \
  131. }
  132. NS_ASSUME_NONNULL_END