RCTShadowView.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /*
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. */
  7. #import <UIKit/UIKit.h>
  8. #import <React/RCTComponent.h>
  9. #import <React/RCTLayout.h>
  10. #import <React/RCTRootView.h>
  11. #import <yoga/Yoga.h>
  12. @class RCTRootShadowView;
  13. @class RCTSparseArray;
  14. typedef void (^RCTApplierBlock)(NSDictionary<NSNumber *, UIView *> *viewRegistry);
  15. /**
  16. * ShadowView tree mirrors RCT view tree. Every node is highly stateful.
  17. * 1. A node is in one of three lifecycles: uninitialized, computed, dirtied.
  18. * 1. RCTBridge may call any of the padding/margin/width/height/top/left setters. A setter would dirty
  19. * the node and all of its ancestors.
  20. * 2. At the end of each Bridge transaction, we call layoutWithMinimumSize:maximumSize:layoutDirection:layoutContext
  21. * at the root node to recursively lay out the entire hierarchy.
  22. * 3. If a node is "computed" and the constraint passed from above is identical to the constraint used to
  23. * perform the last computation, we skip laying out the subtree entirely.
  24. */
  25. @interface RCTShadowView : NSObject <RCTComponent>
  26. /**
  27. * Yoga Config which will be used to create `yogaNode` property.
  28. * Override in subclass to enable special Yoga features.
  29. * Defaults to suitable to current device configuration.
  30. */
  31. + (YGConfigRef)yogaConfig;
  32. /**
  33. * RCTComponent interface.
  34. */
  35. - (NSArray<RCTShadowView *> *)reactSubviews NS_REQUIRES_SUPER;
  36. - (RCTShadowView *)reactSuperview NS_REQUIRES_SUPER;
  37. - (void)insertReactSubview:(RCTShadowView *)subview atIndex:(NSInteger)atIndex NS_REQUIRES_SUPER;
  38. - (void)removeReactSubview:(RCTShadowView *)subview NS_REQUIRES_SUPER;
  39. @property (nonatomic, weak, readonly) RCTRootShadowView *rootView;
  40. @property (nonatomic, weak, readonly) RCTShadowView *superview;
  41. @property (nonatomic, assign, readonly) YGNodeRef yogaNode;
  42. @property (nonatomic, copy) NSString *viewName;
  43. @property (nonatomic, copy) RCTDirectEventBlock onLayout;
  44. /**
  45. * Computed layout of the view.
  46. */
  47. @property (nonatomic, assign) RCTLayoutMetrics layoutMetrics;
  48. /**
  49. * In some cases we need a way to specify some environmental data to shadow view
  50. * to improve layout (or do something similar), so `localData` serves these needs.
  51. * For example, any stateful embedded native views may benefit from this.
  52. * Have in mind that this data is not supposed to interfere with the state of
  53. * the shadow view.
  54. * Please respect one-directional data flow of React.
  55. * Use `-[RCTUIManager setLocalData:forView:]` to set this property
  56. * (to provide local/environmental data for a shadow view) from the main thread.
  57. */
  58. - (void)setLocalData:(NSObject *)localData;
  59. /**
  60. * isNewView - Used to track the first time the view is introduced into the hierarchy. It is initialized YES, then is
  61. * set to NO in RCTUIManager after the layout pass is done and all frames have been extracted to be applied to the
  62. * corresponding UIViews.
  63. */
  64. @property (nonatomic, assign, getter=isNewView) BOOL newView;
  65. /**
  66. * Position and dimensions.
  67. * Defaults to { 0, 0, NAN, NAN }.
  68. */
  69. @property (nonatomic, assign) YGValue top;
  70. @property (nonatomic, assign) YGValue left;
  71. @property (nonatomic, assign) YGValue bottom;
  72. @property (nonatomic, assign) YGValue right;
  73. @property (nonatomic, assign) YGValue start;
  74. @property (nonatomic, assign) YGValue end;
  75. @property (nonatomic, assign) YGValue width;
  76. @property (nonatomic, assign) YGValue height;
  77. @property (nonatomic, assign) YGValue minWidth;
  78. @property (nonatomic, assign) YGValue maxWidth;
  79. @property (nonatomic, assign) YGValue minHeight;
  80. @property (nonatomic, assign) YGValue maxHeight;
  81. /**
  82. * Convenient alias to `width` and `height` in pixels.
  83. * Defaults to NAN in case of non-pixel dimension.
  84. */
  85. @property (nonatomic, assign) CGSize size;
  86. /**
  87. * Border. Defaults to { 0, 0, 0, 0 }.
  88. */
  89. @property (nonatomic, assign) float borderWidth;
  90. @property (nonatomic, assign) float borderTopWidth;
  91. @property (nonatomic, assign) float borderLeftWidth;
  92. @property (nonatomic, assign) float borderBottomWidth;
  93. @property (nonatomic, assign) float borderRightWidth;
  94. @property (nonatomic, assign) float borderStartWidth;
  95. @property (nonatomic, assign) float borderEndWidth;
  96. /**
  97. * Margin. Defaults to { 0, 0, 0, 0 }.
  98. */
  99. @property (nonatomic, assign) YGValue margin;
  100. @property (nonatomic, assign) YGValue marginVertical;
  101. @property (nonatomic, assign) YGValue marginHorizontal;
  102. @property (nonatomic, assign) YGValue marginTop;
  103. @property (nonatomic, assign) YGValue marginLeft;
  104. @property (nonatomic, assign) YGValue marginBottom;
  105. @property (nonatomic, assign) YGValue marginRight;
  106. @property (nonatomic, assign) YGValue marginStart;
  107. @property (nonatomic, assign) YGValue marginEnd;
  108. /**
  109. * Padding. Defaults to { 0, 0, 0, 0 }.
  110. */
  111. @property (nonatomic, assign) YGValue padding;
  112. @property (nonatomic, assign) YGValue paddingVertical;
  113. @property (nonatomic, assign) YGValue paddingHorizontal;
  114. @property (nonatomic, assign) YGValue paddingTop;
  115. @property (nonatomic, assign) YGValue paddingLeft;
  116. @property (nonatomic, assign) YGValue paddingBottom;
  117. @property (nonatomic, assign) YGValue paddingRight;
  118. @property (nonatomic, assign) YGValue paddingStart;
  119. @property (nonatomic, assign) YGValue paddingEnd;
  120. /**
  121. * Flexbox properties. All zero/disabled by default
  122. */
  123. @property (nonatomic, assign) YGFlexDirection flexDirection;
  124. @property (nonatomic, assign) YGJustify justifyContent;
  125. @property (nonatomic, assign) YGAlign alignSelf;
  126. @property (nonatomic, assign) YGAlign alignItems;
  127. @property (nonatomic, assign) YGAlign alignContent;
  128. @property (nonatomic, assign) YGPositionType position;
  129. @property (nonatomic, assign) YGWrap flexWrap;
  130. @property (nonatomic, assign) YGDisplay display;
  131. @property (nonatomic, assign) float flex;
  132. @property (nonatomic, assign) float flexGrow;
  133. @property (nonatomic, assign) float flexShrink;
  134. @property (nonatomic, assign) YGValue flexBasis;
  135. @property (nonatomic, assign) float aspectRatio;
  136. /**
  137. * Interface direction (LTR or RTL)
  138. */
  139. @property (nonatomic, assign) YGDirection direction;
  140. /**
  141. * Clipping properties
  142. */
  143. @property (nonatomic, assign) YGOverflow overflow;
  144. /**
  145. * Represents the natural size of the view, which is used when explicit size is not set or is ambiguous.
  146. * Defaults to `{UIViewNoIntrinsicMetric, UIViewNoIntrinsicMetric}`.
  147. */
  148. @property (nonatomic, assign) CGSize intrinsicContentSize;
  149. #pragma mark - Layout
  150. /**
  151. * Initiates layout starts from the view.
  152. */
  153. - (void)layoutWithMinimumSize:(CGSize)minimumSize
  154. maximumSize:(CGSize)maximumSize
  155. layoutDirection:(UIUserInterfaceLayoutDirection)layoutDirection
  156. layoutContext:(RCTLayoutContext)layoutContext;
  157. /**
  158. * Applies computed layout metrics to the view.
  159. */
  160. - (void)layoutWithMetrics:(RCTLayoutMetrics)layoutMetrics layoutContext:(RCTLayoutContext)layoutContext;
  161. /**
  162. * Calculates (if needed) and applies layout to subviews.
  163. */
  164. - (void)layoutSubviewsWithContext:(RCTLayoutContext)layoutContext;
  165. /**
  166. * Measures shadow view without side-effects.
  167. * Default implementation uses Yoga for measuring.
  168. */
  169. - (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize;
  170. /**
  171. * Returns whether or not this view can have any subviews.
  172. * Adding/inserting a child view to leaf view (`canHaveSubviews` equals `NO`)
  173. * will throw an error.
  174. * Return `NO` for components which must not have any descendants
  175. * (like <Image>, for example.)
  176. * Defaults to `YES`. Can be overridden in subclasses.
  177. * Don't confuse this with `isYogaLeafNode`.
  178. */
  179. - (BOOL)canHaveSubviews;
  180. /**
  181. * Returns whether or not this node acts as a leaf node in the eyes of Yoga.
  182. * For example `RCTTextShadowView` has children which it does not want Yoga
  183. * to lay out so in the eyes of Yoga it is a leaf node.
  184. * Defaults to `NO`. Can be overridden in subclasses.
  185. * Don't confuse this with `canHaveSubviews`.
  186. */
  187. - (BOOL)isYogaLeafNode;
  188. /**
  189. * As described in RCTComponent protocol.
  190. */
  191. - (void)didUpdateReactSubviews NS_REQUIRES_SUPER;
  192. - (void)didSetProps:(NSArray<NSString *> *)changedProps NS_REQUIRES_SUPER;
  193. /**
  194. * Computes the recursive offset, meaning the sum of all descendant offsets -
  195. * this is the sum of all positions inset from parents. This is not merely the
  196. * sum of `top`/`left`s, as this function uses the *actual* positions of
  197. * children, not the style specified positions - it computes this based on the
  198. * resulting layout. It does not yet compensate for native scroll view insets or
  199. * transforms or anchor points.
  200. */
  201. - (CGRect)measureLayoutRelativeToAncestor:(RCTShadowView *)ancestor;
  202. /**
  203. * Checks if the current shadow view is a descendant of the provided `ancestor`
  204. */
  205. - (BOOL)viewIsDescendantOf:(RCTShadowView *)ancestor;
  206. @end