1 import React 2 3 func DevMenuUIEdgeInsetsEqualToEdgeInsetsWithThreshold(_ insets1: UIEdgeInsets, _ insets2: UIEdgeInsets, _ threshold: CGFloat) -> Bool { 4 return abs(insets1.left - insets2.left) <= threshold && 5 abs(insets1.right - insets2.right) <= threshold && 6 abs(insets1.top - insets2.top) <= threshold && 7 abs(insets1.bottom - insets2.bottom) <= threshold 8 } 9 10 extension UIView { 11 var nativeSafeAreaSupport: Bool { 12 return responds(to: #selector(getter: safeAreaInsets)) 13 } 14 15 func safeAreaInsetsOrEmulate() -> UIEdgeInsets { 16 if nativeSafeAreaSupport { 17 if #available(iOS 11.0, *) { 18 return safeAreaInsets 19 } 20 } 21 return emulatedSafeAreaInsets() 22 } 23 24 func emulatedSafeAreaInsets() -> UIEdgeInsets { 25 guard let vc = self.reactViewController() else { 26 return .zero 27 } 28 29 let topLayoutOffset = vc.topLayoutGuide.length 30 let bottomLayoutOffset = vc.bottomLayoutGuide.length 31 var safeArea = vc.view.bounds 32 safeArea.origin.y += topLayoutOffset 33 safeArea.size.height -= topLayoutOffset + bottomLayoutOffset 34 let localSafeArea = vc.view.convert(safeArea, to: self) 35 var safeAreaInsets = UIEdgeInsets.zero 36 37 if localSafeArea.minY > bounds.minY { 38 safeAreaInsets.top = localSafeArea.minY - bounds.minY 39 } 40 41 if localSafeArea.maxY < bounds.maxY { 42 safeAreaInsets.bottom = bounds.maxY - localSafeArea.maxY 43 } 44 45 return safeAreaInsets 46 } 47 } 48