void CKComponentAttachControllerAttachComponentRootLayout()

in ComponentKit/Core/CKComponentAttachController.mm [62:103]


void CKComponentAttachControllerAttachComponentRootLayout(
    CKComponentAttachController *const self,
    const CKComponentAttachControllerAttachComponentRootLayoutParams &params)
{
  RCCAssertMainThread();
  if (self == nil) {
    RCCAssert(self, @"Impossible to attach a component layout to a nil attachController");
    return;
  }

  const auto view = params.view;
  UIView *currentlyAttachedView = self->_scopeIdentifierToAttachedViewMap[@(params.scopeIdentifier)];
  // If the component tree currently attached to the view is different from the one we want to attach
  if (currentlyAttachedView != view) {
    // 1 - If the component layout want to attach is currently attached somewhere else then detach it
    [self _detachComponentLayoutFromView:currentlyAttachedView];
    // 2 - Unmount the component tree currently in the view we want to attach our component layout to
    [self _detachComponentLayoutFromView:view];
  }

  const auto &prevLayout = [&]() {
    if (const auto layoutProvider = [self->_scopeIdentifierToLayoutProvider objectForKey:@(params.scopeIdentifier)]) {
      return layoutProvider.rootLayout;
    } else {
      return CKComponentRootLayout {};
    }
  }();
  // Mount the component tree on the view
  const auto &layout = params.layoutProvider ? params.layoutProvider.rootLayout : CKComponentRootLayout {};
  const auto attachState = mountComponentLayoutInView(layout,
                                                      prevLayout,
                                                      view,
                                                      params.scopeIdentifier,
                                                      params.boundsAnimation,
                                                      params.analyticsListener);
  // Mark the view as attached and associates it to the right attach state
  self->_scopeIdentifierToAttachedViewMap[@(params.scopeIdentifier)] = view;
  // Save layout provider in map, it will be used for figuring out animations between two layouts.
  [self->_scopeIdentifierToLayoutProvider setObject:params.layoutProvider
                                             forKey:@(params.scopeIdentifier)];
  CKSetAttachStateForView(view, attachState);
}