first commit

This commit is contained in:
2026-03-10 16:18:05 +00:00
commit 11f9c069b5
31635 changed files with 3187747 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
import UIKit
/// Instead of casting to concrete class names (which break on renames),
/// we detect tab views by checking `responds(to:)` for expected selectors
/// and read properties via KVC.
enum RNScreensTabCompat {
private static let tabKeyName = "tabKey"
private static let controllerName = "controller"
private static let reactViewControllerName = "reactViewController"
private static let tabKeySelector = NSSelectorFromString(tabKeyName)
private static let controllerSelector = NSSelectorFromString(controllerName)
private static let reactViewControllerSelector = NSSelectorFromString(reactViewControllerName)
// MARK: - Type check
/// A view is a tab screen if it has a `tabKey` property specific to RNScreens tab views.
static func isTabScreen(_ view: UIView) -> Bool {
view.responds(to: tabKeySelector)
}
// MARK: - Property access via KVC
static func tabKey(from view: UIView) -> String? {
guard view.responds(to: tabKeySelector) else { return nil }
return view.value(forKey: tabKeyName) as? String
}
/// Calls `reactViewController()` dynamically via `perform(_:)`, then returns `.tabBarController`.
static func tabBarController(fromTabScreen view: UIView) -> UITabBarController? {
guard isTabScreen(view),
view.responds(to: reactViewControllerSelector)
else { return nil }
let vc = view.perform(reactViewControllerSelector)?.takeUnretainedValue() as? UIViewController
return vc?.tabBarController
}
static func tabBarController(fromTabHost view: UIView) -> UITabBarController? {
guard view.responds(to: controllerSelector) else { return nil }
return view.value(forKey: controllerName) as? UITabBarController
}
}