RCTWrapperViewController.m 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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 "RCTWrapperViewController.h"
  8. #import <UIKit/UIScrollView.h>
  9. #import "RCTAutoInsetsProtocol.h"
  10. #import "RCTEventDispatcher.h"
  11. #import "RCTUtils.h"
  12. #import "UIView+React.h"
  13. @implementation RCTWrapperViewController {
  14. UIView *_wrapperView;
  15. UIView *_contentView;
  16. RCTEventDispatcher *_eventDispatcher;
  17. CGFloat _previousTopLayoutLength;
  18. CGFloat _previousBottomLayoutLength;
  19. id<UILayoutSupport> _currentTopLayoutGuide;
  20. id<UILayoutSupport> _currentBottomLayoutGuide;
  21. }
  22. - (instancetype)initWithContentView:(UIView *)contentView
  23. {
  24. RCTAssertParam(contentView);
  25. if ((self = [super initWithNibName:nil bundle:nil])) {
  26. _contentView = contentView;
  27. self.automaticallyAdjustsScrollViewInsets = NO;
  28. }
  29. return self;
  30. }
  31. RCT_NOT_IMPLEMENTED(-(instancetype)initWithNibName : (NSString *)nn bundle : (NSBundle *)nb)
  32. RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
  33. - (void)viewWillLayoutSubviews
  34. {
  35. [super viewWillLayoutSubviews];
  36. _currentTopLayoutGuide = self.topLayoutGuide;
  37. _currentBottomLayoutGuide = self.bottomLayoutGuide;
  38. }
  39. static BOOL RCTFindScrollViewAndRefreshContentInsetInView(UIView *view)
  40. {
  41. if ([view conformsToProtocol:@protocol(RCTAutoInsetsProtocol)]) {
  42. [(id<RCTAutoInsetsProtocol>)view refreshContentInset];
  43. return YES;
  44. }
  45. for (UIView *subview in view.subviews) {
  46. if (RCTFindScrollViewAndRefreshContentInsetInView(subview)) {
  47. return YES;
  48. }
  49. }
  50. return NO;
  51. }
  52. - (void)viewDidLayoutSubviews
  53. {
  54. [super viewDidLayoutSubviews];
  55. if (_previousTopLayoutLength != _currentTopLayoutGuide.length ||
  56. _previousBottomLayoutLength != _currentBottomLayoutGuide.length) {
  57. RCTFindScrollViewAndRefreshContentInsetInView(_contentView);
  58. _previousTopLayoutLength = _currentTopLayoutGuide.length;
  59. _previousBottomLayoutLength = _currentBottomLayoutGuide.length;
  60. }
  61. }
  62. - (void)loadView
  63. {
  64. // Add a wrapper so that the wrapper view managed by the
  65. // UINavigationController doesn't end up resetting the frames for
  66. //`contentView` which is a react-managed view.
  67. _wrapperView = [[UIView alloc] initWithFrame:_contentView.bounds];
  68. [_wrapperView addSubview:_contentView];
  69. self.view = _wrapperView;
  70. }
  71. @end