RCTSurfaceHostingComponentController.mm 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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 "RCTSurfaceHostingComponentController.h"
  8. #import <ComponentKit/CKComponentSubclass.h>
  9. #import <React/RCTAssert.h>
  10. #import <React/RCTSurface.h>
  11. #import <React/RCTSurfaceDelegate.h>
  12. #import <React/RCTSurfaceView.h>
  13. #import "RCTSurfaceHostingComponent+Internal.h"
  14. #import "RCTSurfaceHostingComponent.h"
  15. #import "RCTSurfaceHostingComponentState.h"
  16. @interface RCTSurfaceHostingComponentController() <RCTSurfaceDelegate>
  17. @end
  18. @implementation RCTSurfaceHostingComponentController {
  19. RCTSurface *_surface;
  20. }
  21. - (instancetype)initWithComponent:(RCTSurfaceHostingComponent *)component
  22. {
  23. if (self = [super initWithComponent:component]) {
  24. [self updateSurfaceWithComponent:component];
  25. }
  26. return self;
  27. }
  28. #pragma mark - Lifecycle
  29. - (void)didMount
  30. {
  31. [super didMount];
  32. [self mountSurfaceView];
  33. }
  34. - (void)didRemount
  35. {
  36. [super didRemount];
  37. [self mountSurfaceView];
  38. }
  39. - (void)didUpdateComponent
  40. {
  41. [super didUpdateComponent];
  42. [self updateSurfaceWithComponent:(RCTSurfaceHostingComponent *)self.component];
  43. }
  44. - (void)didUnmount
  45. {
  46. [super didUnmount];
  47. [self unmountSurfaceView];
  48. }
  49. #pragma mark - Helpers
  50. - (void)updateSurfaceWithComponent:(RCTSurfaceHostingComponent *)component
  51. {
  52. // Updating `surface`
  53. RCTSurface *const surface = component.surface;
  54. if (surface != _surface) {
  55. if (_surface.delegate == self) {
  56. _surface.delegate = nil;
  57. }
  58. _surface = surface;
  59. _surface.delegate = self;
  60. }
  61. }
  62. - (void)setIntrinsicSize:(CGSize)intrinsicSize
  63. {
  64. [self.component updateState:^(RCTSurfaceHostingComponentState *state) {
  65. return [RCTSurfaceHostingComponentState newWithStage:state.stage
  66. intrinsicSize:intrinsicSize];
  67. } mode:[self suitableStateUpdateMode]];
  68. }
  69. - (void)setStage:(RCTSurfaceStage)stage
  70. {
  71. [self.component updateState:^(RCTSurfaceHostingComponentState *state) {
  72. return [RCTSurfaceHostingComponentState newWithStage:stage
  73. intrinsicSize:state.intrinsicSize];
  74. } mode:[self suitableStateUpdateMode]];
  75. }
  76. - (CKUpdateMode)suitableStateUpdateMode
  77. {
  78. return ((RCTSurfaceHostingComponent *)self.component).options.synchronousStateUpdates && RCTIsMainQueue() ? CKUpdateModeSynchronous : CKUpdateModeAsynchronous;
  79. }
  80. - (void)mountSurfaceView
  81. {
  82. UIView *const surfaceView = _surface.view;
  83. const CKComponentViewContext &context = [[self component] viewContext];
  84. UIView *const superview = context.view;
  85. superview.clipsToBounds = YES;
  86. RCTAssert([superview.subviews count] <= 1, @"Should never have more than a single stateful subview.");
  87. UIView *const existingSurfaceView = [superview.subviews lastObject];
  88. if (existingSurfaceView != surfaceView) {
  89. [existingSurfaceView removeFromSuperview];
  90. surfaceView.frame = superview.bounds;
  91. surfaceView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  92. [superview addSubview:surfaceView];
  93. }
  94. }
  95. - (void)unmountSurfaceView
  96. {
  97. const CKComponentViewContext &context = [[self component] viewContext];
  98. UIView *const superview = context.view;
  99. RCTAssert([superview.subviews count] <= 1, @"Should never have more than a single stateful subview.");
  100. UIView *const existingSurfaceView = [superview.subviews lastObject];
  101. [existingSurfaceView removeFromSuperview];
  102. }
  103. #pragma mark - RCTSurfaceDelegate
  104. - (void)surface:(RCTSurface *)surface didChangeIntrinsicSize:(CGSize)intrinsicSize
  105. {
  106. [self setIntrinsicSize:intrinsicSize];
  107. }
  108. - (void)surface:(RCTSurface *)surface didChangeStage:(RCTSurfaceStage)stage
  109. {
  110. [self setStage:stage];
  111. }
  112. @end