FLEXHierarchyViewController.m 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. //
  2. // FLEXHierarchyViewController.m
  3. // FLEX
  4. //
  5. // Created by Tanner Bennett on 1/9/20.
  6. // Copyright © 2020 Flipboard. 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. // 3D toggle button
  57. self.treeViewController.navigationItem.leftBarButtonItem = [UIBarButtonItem
  58. itemWithImage:FLEXResources.toggle3DIcon target:self action:@selector(toggleHierarchyMode)
  59. ];
  60. // Dismiss when tree view row is selected
  61. __weak id<FLEXHierarchyDelegate> delegate = self.hierarchyDelegate;
  62. self.treeViewController.didSelectRowAction = ^(UIView *selectedView) {
  63. [delegate viewHierarchyDidDismiss:selectedView];
  64. };
  65. // Start of in tree view
  66. _mode = FLEXHierarchyViewModeTree;
  67. [self pushViewController:self.treeViewController animated:NO];
  68. }
  69. - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
  70. // Done button: manually added here because the hierarhcy screens need to actually pass
  71. // data back to the explorer view controller so that it can highlight selected views
  72. viewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
  73. initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(donePressed)
  74. ];
  75. [super pushViewController:viewController animated:animated];
  76. }
  77. #pragma mark - Private
  78. - (void)donePressed {
  79. // We need to manually close ourselves here because
  80. // FLEXNavigationController doesn't ever close tabs itself
  81. [FLEXTabList.sharedList closeTab:self];
  82. [self.hierarchyDelegate viewHierarchyDidDismiss:self.selectedView];
  83. }
  84. - (void)toggleHierarchyMode {
  85. switch (self.mode) {
  86. case FLEXHierarchyViewModeTree:
  87. self.mode = FLEXHierarchyViewMode3DSnapshot;
  88. break;
  89. case FLEXHierarchyViewMode3DSnapshot:
  90. self.mode = FLEXHierarchyViewModeTree;
  91. break;
  92. }
  93. }
  94. - (void)setMode:(FLEXHierarchyViewMode)mode {
  95. if (mode != _mode) {
  96. // The tree view controller is our top stack view controller, and
  97. // changing the mode simply pushes the snapshot view. In the future,
  98. // I would like to have the 3D toggle button transparently switch
  99. // between two views instead of pushing a new view controller.
  100. // This way the views should share the search controller somehow.
  101. switch (mode) {
  102. case FLEXHierarchyViewModeTree:
  103. [self popViewControllerAnimated:NO];
  104. self.toolbarHidden = YES;
  105. self.treeViewController.selectedView = self.selectedView;
  106. break;
  107. case FLEXHierarchyViewMode3DSnapshot:
  108. [self pushViewController:self.snapshotViewController animated:NO];
  109. self.toolbarHidden = NO;
  110. self.snapshotViewController.selectedView = self.selectedView;
  111. break;
  112. }
  113. // Change this last so that self.selectedView works right above
  114. _mode = mode;
  115. }
  116. }
  117. - (UIView *)selectedView {
  118. switch (self.mode) {
  119. case FLEXHierarchyViewModeTree:
  120. return self.treeViewController.selectedView;
  121. case FLEXHierarchyViewMode3DSnapshot:
  122. return self.snapshotViewController.selectedView;
  123. }
  124. }
  125. @end