123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- //
- // UIViewController.swift
- // Mastodon
- //
- // Created by Cirno MainasuK on 2021-1-27.
- //
- import UIKit
- extension UIViewController {
-
- /// Returns the top most view controller from given view controller's stack.
- var topMost: UIViewController? {
- // presented view controller
- if let presentedViewController = presentedViewController {
- return presentedViewController.topMost
- }
-
- // UITabBarController
- if let tabBarController = self as? UITabBarController,
- let selectedViewController = tabBarController.selectedViewController {
- return selectedViewController.topMost
- }
-
- // UINavigationController
- if let navigationController = self as? UINavigationController,
- let visibleViewController = navigationController.visibleViewController {
- return visibleViewController.topMost
- }
-
- // UIPageController
- if let pageViewController = self as? UIPageViewController,
- pageViewController.viewControllers?.count == 1 {
- return pageViewController.viewControllers?.first?.topMost ?? self
- }
-
- // child view controller
- for subview in self.view?.subviews ?? [] {
- if let childViewController = subview.next as? UIViewController {
- return childViewController.topMost
- }
- }
-
- return self
- }
-
- }
- extension UIViewController {
- func viewController<T: UIViewController>(of type: T.Type) -> T? {
- if let viewController = self as? T {
- return viewController
- }
-
- // UITabBarController
- if let tabBarController = self as? UITabBarController {
- for tab in tabBarController.viewControllers ?? [] {
- if let viewController = tab.viewController(of: type) {
- return viewController
- }
- }
- }
-
- // UINavigationController
- if let navigationController = self as? UINavigationController {
- for page in navigationController.viewControllers {
- if let viewController = page.viewController(of: type) {
- return viewController
- }
- }
- }
-
- // UIPageController
- if let pageViewController = self as? UIPageViewController {
- for page in pageViewController.viewControllers ?? [] {
- if let viewController = page.viewController(of: type) {
- return viewController
- }
- }
- }
-
- // child view controller
- for subview in self.view?.subviews ?? [] {
- if let childViewController = subview.next as? UIViewController,
- let viewController = childViewController.viewController(of: type) {
- return viewController
- }
- }
-
- return nil
- }
-
- }
- extension UIViewController {
-
- /// https://bluelemonbits.com/2018/08/26/inserting-cells-at-the-top-of-a-uitableview-with-no-scrolling/
- static func topVisibleTableViewCellIndexPath(in tableView: UITableView, navigationBar: UINavigationBar) -> IndexPath? {
- let navigationBarRectInTableView = tableView.convert(navigationBar.bounds, from: navigationBar)
- let navigationBarMaxYPosition = CGPoint(x: 0, y: navigationBarRectInTableView.origin.y + navigationBarRectInTableView.size.height + 1) // +1pt for UIKit cell locate
- let mostTopVisiableIndexPath = tableView.indexPathForRow(at: navigationBarMaxYPosition)
- return mostTopVisiableIndexPath
- }
-
- static func tableViewCellOriginOffsetToWindowTop(in tableView: UITableView, at indexPath: IndexPath, navigationBar: UINavigationBar) -> CGFloat {
- let rectForTopRow = tableView.rectForRow(at: indexPath)
- let navigationBarRectInTableView = tableView.convert(navigationBar.bounds, from: navigationBar)
- let navigationBarMaxYPosition = CGPoint(x: 0, y: navigationBarRectInTableView.origin.y + navigationBarRectInTableView.size.height) // without +1pt
- let differenceBetweenTopRowAndNavigationBar = rectForTopRow.origin.y - navigationBarMaxYPosition.y
- return differenceBetweenTopRowAndNavigationBar
- }
-
- }
- extension UIViewController {
-
- /// https://stackoverflow.com/a/27301207/3797903
- var isModal: Bool {
- let presentingIsModal = presentingViewController != nil
- let presentingIsNavigation = navigationController != nil && navigationController?.presentingViewController?.presentedViewController == navigationController
- let presentingIsTabBar = tabBarController?.presentingViewController is UITabBarController
- return presentingIsModal || presentingIsNavigation || presentingIsTabBar
- }
-
- }
|