Ei kuvausta

RNCSafeAreaView.m 2.4KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // Simplified version of https://github.com/facebook/react-native/blob/master/React/Views/SafeAreaView/RCTSafeAreaView.m
  2. #import "RNCSafeAreaView.h"
  3. #import <React/RCTBridge.h>
  4. #import <React/RCTUIManager.h>
  5. @implementation RNCSafeAreaView {
  6. UIEdgeInsets _currentSafeAreaInsets;
  7. }
  8. RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)decoder)
  9. RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame)
  10. - (BOOL)isSupportedByOS
  11. {
  12. return [self respondsToSelector:@selector(safeAreaInsets)];
  13. }
  14. - (UIEdgeInsets)realOrEmulateSafeAreaInsets
  15. {
  16. #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
  17. if (self.isSupportedByOS) {
  18. if (@available(iOS 11.0, *)) {
  19. return self.safeAreaInsets;
  20. }
  21. }
  22. #endif
  23. return self.emulatedSafeAreaInsets;
  24. }
  25. - (UIEdgeInsets)emulatedSafeAreaInsets
  26. {
  27. UIViewController* vc = self.reactViewController;
  28. if (!vc) {
  29. return UIEdgeInsetsZero;
  30. }
  31. CGFloat topLayoutOffset = vc.topLayoutGuide.length;
  32. CGFloat bottomLayoutOffset = vc.bottomLayoutGuide.length;
  33. CGRect safeArea = vc.view.bounds;
  34. safeArea.origin.y += topLayoutOffset;
  35. safeArea.size.height -= topLayoutOffset + bottomLayoutOffset;
  36. CGRect localSafeArea = [vc.view convertRect:safeArea toView:self];
  37. UIEdgeInsets safeAreaInsets = UIEdgeInsetsMake(0, 0, 0, 0);
  38. if (CGRectGetMinY(localSafeArea) > CGRectGetMinY(self.bounds)) {
  39. safeAreaInsets.top = CGRectGetMinY(localSafeArea) - CGRectGetMinY(self.bounds);
  40. }
  41. if (CGRectGetMaxY(localSafeArea) < CGRectGetMaxY(self.bounds)) {
  42. safeAreaInsets.bottom = CGRectGetMaxY(self.bounds) - CGRectGetMaxY(localSafeArea);
  43. }
  44. return safeAreaInsets;
  45. }
  46. static BOOL UIEdgeInsetsEqualToEdgeInsetsWithThreshold(UIEdgeInsets insets1, UIEdgeInsets insets2, CGFloat threshold) {
  47. return
  48. ABS(insets1.left - insets2.left) <= threshold &&
  49. ABS(insets1.right - insets2.right) <= threshold &&
  50. ABS(insets1.top - insets2.top) <= threshold &&
  51. ABS(insets1.bottom - insets2.bottom) <= threshold;
  52. }
  53. - (void)safeAreaInsetsDidChange
  54. {
  55. [self invalidateSafeAreaInsets];
  56. }
  57. - (void)invalidateSafeAreaInsets
  58. {
  59. UIEdgeInsets safeAreaInsets = [self realOrEmulateSafeAreaInsets];
  60. self.onInsetsChange(@{
  61. @"top": @(safeAreaInsets.top),
  62. });
  63. }
  64. - (void)layoutSubviews
  65. {
  66. [super layoutSubviews];
  67. if (!self.isSupportedByOS) {
  68. [self invalidateSafeAreaInsets];
  69. }
  70. }
  71. @end