FLEXHierarchyViewController.m 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. //
  2. // FLEXHierarchyViewController.m
  3. // FLEX
  4. //
  5. // Created by Tanner Bennett on 1/9/20.
  6. // Copyright © 2020 FLEX Team. All rights reserved.
  7. //
  8. #import "FLEXHierarchyViewController.h"
  9. #import "FLEXHierarchyTableViewController.h"
  10. #import "FHSViewController.h"
  11. #import "FLEXUtility.h"
  12. #import "FLEXTabList.h"
  13. #import "FLEXResources.h"
  14. #import "UIBarButtonItem+FLEX.h"
  15. typedef NS_ENUM(NSUInteger, FLEXHierarchyViewMode) {
  16. FLEXHierarchyViewModeTree = 1,
  17. FLEXHierarchyViewMode3DSnapshot
  18. };
  19. @interface FLEXHierarchyViewController ()
  20. @property (nonatomic, readonly, weak) id<FLEXHierarchyDelegate> hierarchyDelegate;
  21. @property (nonatomic, readonly) FHSViewController *snapshotViewController;
  22. @property (nonatomic, readonly) FLEXHierarchyTableViewController *treeViewController;
  23. @property (nonatomic) FLEXHierarchyViewMode mode;
  24. @property (nonatomic, readonly) UIView *selectedView;
  25. @end
  26. @implementation FLEXHierarchyViewController
  27. #pragma mark - Initialization
  28. + (instancetype)delegate:(id<FLEXHierarchyDelegate>)delegate {
  29. return [self delegate:delegate viewsAtTap:nil selectedView:nil];
  30. }
  31. + (instancetype)delegate:(id<FLEXHierarchyDelegate>)delegate
  32. viewsAtTap:(NSArray<UIView *> *)viewsAtTap
  33. selectedView:(UIView *)selectedView {
  34. return [[self alloc] initWithDelegate:delegate viewsAtTap:viewsAtTap selectedView:selectedView];
  35. }
  36. - (id)initWithDelegate:(id)delegate viewsAtTap:(NSArray<UIView *> *)viewsAtTap selectedView:(UIView *)view {
  37. self = [super init];
  38. if (self) {
  39. NSArray<UIWindow *> *allWindows = FLEXUtility.allWindows;
  40. _hierarchyDelegate = delegate;
  41. _treeViewController = [FLEXHierarchyTableViewController
  42. windows:allWindows viewsAtTap:viewsAtTap selectedView:view
  43. ];
  44. if (viewsAtTap) {
  45. _snapshotViewController = [FHSViewController snapshotViewsAtTap:viewsAtTap selectedView:view];
  46. } else {
  47. _snapshotViewController = [FHSViewController snapshotWindows:allWindows];
  48. }
  49. self.modalPresentationStyle = UIModalPresentationFullScreen;
  50. }
  51. return self;
  52. }
  53. #pragma mark - Lifecycle
  54. - (void)viewDidLoad {
  55. [super viewDidLoad];
  56. #if !TARGET_OS_TV
  57. // 3D toggle button
  58. self.treeViewController.navigationItem.leftBarButtonItem = [UIBarButtonItem
  59. flex_itemWithImage:FLEXResources.toggle3DIcon target:self action:@selector(toggleHierarchyMode)
  60. ];
  61. #endif
  62. // Dismiss when tree view row is selected
  63. __weak id<FLEXHierarchyDelegate> delegate = self.hierarchyDelegate;
  64. self.treeViewController.didSelectRowAction = ^(UIView *selectedView) {
  65. [delegate viewHierarchyDidDismiss:selectedView];
  66. };
  67. // Start of in tree view
  68. _mode = FLEXHierarchyViewModeTree;
  69. [self pushViewController:self.treeViewController animated:NO];
  70. }
  71. - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
  72. // Done button: manually added here because the hierarhcy screens need to actually pass
  73. // data back to the explorer view controller so that it can highlight selected views
  74. viewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
  75. initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(donePressed)
  76. ];
  77. [super pushViewController:viewController animated:animated];
  78. }
  79. #pragma mark - Private
  80. - (void)donePressed {
  81. // We need to manually close ourselves here because
  82. // FLEXNavigationController doesn't ever close tabs itself
  83. [FLEXTabList.sharedList closeTab:self];
  84. [self.hierarchyDelegate viewHierarchyDidDismiss:self.selectedView];
  85. }
  86. - (void)toggleHierarchyMode {
  87. switch (self.mode) {
  88. case FLEXHierarchyViewModeTree:
  89. self.mode = FLEXHierarchyViewMode3DSnapshot;
  90. break;
  91. case FLEXHierarchyViewMode3DSnapshot:
  92. self.mode = FLEXHierarchyViewModeTree;
  93. break;
  94. }
  95. }
  96. - (void)setMode:(FLEXHierarchyViewMode)mode {
  97. if (mode != _mode) {
  98. // The tree view controller is our top stack view controller, and
  99. // changing the mode simply pushes the snapshot view. In the future,
  100. // I would like to have the 3D toggle button transparently switch
  101. // between two views instead of pushing a new view controller.
  102. // This way the views should share the search controller somehow.
  103. switch (mode) {
  104. case FLEXHierarchyViewModeTree:
  105. [self popViewControllerAnimated:NO];
  106. #if !TARGET_OS_TV
  107. self.toolbarHidden = YES;
  108. #endif
  109. self.treeViewController.selectedView = self.selectedView;
  110. break;
  111. case FLEXHierarchyViewMode3DSnapshot:
  112. [self pushViewController:self.snapshotViewController animated:NO];
  113. #if !TARGET_OS_TV
  114. self.toolbarHidden = NO;
  115. #endif
  116. self.snapshotViewController.selectedView = self.selectedView;
  117. break;
  118. }
  119. // Change this last so that self.selectedView works right above
  120. _mode = mode;
  121. }
  122. }
  123. - (UIView *)selectedView {
  124. switch (self.mode) {
  125. case FLEXHierarchyViewModeTree:
  126. return self.treeViewController.selectedView;
  127. case FLEXHierarchyViewMode3DSnapshot:
  128. return self.snapshotViewController.selectedView;
  129. }
  130. }
  131. @end