RCTWrapperView.m 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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 "RCTWrapperView.h"
  8. #import <React/RCTBridge.h>
  9. #import <React/RCTUIManager.h>
  10. @implementation RCTWrapperView {
  11. __weak RCTBridge *_bridge;
  12. }
  13. - (instancetype)initWithBridge:(RCTBridge *)bridge
  14. {
  15. if (self = [super initWithFrame:CGRectZero]) {
  16. _bridge = bridge;
  17. __weak __typeof(self) weakSelf = self;
  18. _measureBlock = ^(CGSize minimumSize, CGSize maximumSize) {
  19. __typeof(self) strongSelf = weakSelf;
  20. if (!strongSelf) {
  21. return maximumSize;
  22. }
  23. CGSize size = [strongSelf sizeThatFits:maximumSize];
  24. return CGSizeMake(
  25. MAX(size.width, minimumSize.width),
  26. MAX(size.height, minimumSize.height)
  27. );
  28. };
  29. }
  30. return self;
  31. }
  32. #pragma mark - `contentView`
  33. - (nullable UIView *)contentView
  34. {
  35. return self.subviews.firstObject;
  36. }
  37. - (void)setContentView:(UIView *)contentView
  38. {
  39. while (self.subviews.firstObject) {
  40. [self.subviews.firstObject removeFromSuperview];
  41. }
  42. if (!contentView) {
  43. return;
  44. }
  45. [super addSubview:contentView];
  46. contentView.frame = self.bounds;
  47. contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  48. contentView.translatesAutoresizingMaskIntoConstraints = YES;
  49. }
  50. #pragma mark - Layout
  51. - (void)setNeedsLayout
  52. {
  53. [super setNeedsLayout];
  54. [self invalidateIntrinsicContentSize];
  55. }
  56. - (void)invalidateIntrinsicContentSize
  57. {
  58. [super invalidateIntrinsicContentSize];
  59. // Setting `intrinsicContentSize` dirties the Yoga node and
  60. // enforce Yoga to call `measure` function (backed to `measureBlock`).
  61. [_bridge.uiManager setIntrinsicContentSize:self.intrinsicContentSize forView:self];
  62. }
  63. - (CGSize)intrinsicContentSize
  64. {
  65. return [self sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)];
  66. }
  67. - (CGSize)sizeThatFits:(CGSize)size
  68. {
  69. UIView *contentView = self.contentView;
  70. if (!contentView) {
  71. return [super sizeThatFits:size];
  72. }
  73. return [contentView sizeThatFits:size];
  74. }
  75. @end