RCTInputAccessoryViewContent.m 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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 <React/RCTInputAccessoryViewContent.h>
  8. #import <React/UIView+React.h>
  9. @implementation RCTInputAccessoryViewContent
  10. {
  11. UIView *_safeAreaContainer;
  12. NSLayoutConstraint *_heightConstraint;
  13. }
  14. - (instancetype)init
  15. {
  16. if (self = [super init]) {
  17. _safeAreaContainer = [UIView new];
  18. [self addSubview:_safeAreaContainer];
  19. // Use autolayout to position the view properly and take into account
  20. // safe area insets on iPhone X.
  21. // TODO: Support rotation, anchor to left and right without breaking frame x coordinate (T27974328).
  22. self.autoresizingMask = UIViewAutoresizingFlexibleHeight;
  23. _safeAreaContainer.translatesAutoresizingMaskIntoConstraints = NO;
  24. _heightConstraint = [_safeAreaContainer.heightAnchor constraintEqualToConstant:0];
  25. _heightConstraint.active = YES;
  26. if (@available(iOS 11.0, tvOS 11.0, *)) {
  27. [_safeAreaContainer.bottomAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.bottomAnchor].active = YES;
  28. [_safeAreaContainer.topAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.topAnchor].active = YES;
  29. [_safeAreaContainer.leadingAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.leadingAnchor].active = YES;
  30. [_safeAreaContainer.trailingAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.trailingAnchor].active = YES;
  31. } else {
  32. [_safeAreaContainer.bottomAnchor constraintEqualToAnchor:self.bottomAnchor].active = YES;
  33. [_safeAreaContainer.topAnchor constraintEqualToAnchor:self.topAnchor].active = YES;
  34. [_safeAreaContainer.leadingAnchor constraintEqualToAnchor:self.leadingAnchor].active = YES;
  35. [_safeAreaContainer.trailingAnchor constraintEqualToAnchor:self.trailingAnchor].active = YES;
  36. }
  37. }
  38. return self;
  39. }
  40. - (CGSize)intrinsicContentSize
  41. {
  42. // This is needed so the view size is based on autolayout constraints.
  43. return CGSizeZero;
  44. }
  45. - (void)reactSetFrame:(CGRect)frame
  46. {
  47. // We still need to set the frame here, otherwise it won't be
  48. // measured until moved to the window during the keyboard opening
  49. // animation. If this happens, the height will be animated from 0 to
  50. // its actual size and we don't want that.
  51. [self setFrame:frame];
  52. [_safeAreaContainer setFrame:frame];
  53. _heightConstraint.constant = frame.size.height;
  54. [self layoutIfNeeded];
  55. }
  56. - (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)index
  57. {
  58. [super insertReactSubview:subview atIndex:index];
  59. [_safeAreaContainer insertSubview:subview atIndex:index];
  60. }
  61. - (void)removeReactSubview:(UIView *)subview
  62. {
  63. [super removeReactSubview:subview];
  64. [subview removeFromSuperview];
  65. if ([[_safeAreaContainer subviews] count] == 0 && [self isFirstResponder]) {
  66. [self resignFirstResponder];
  67. }
  68. }
  69. @end