LKS_PerspectiveManager.m 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #ifdef SHOULD_COMPILE_LOOKIN_SERVER
  2. //
  3. // LKS_PerspectiveManager.m
  4. // LookinServer
  5. //
  6. // Created by Li Kai on 2019/5/17.
  7. // https://lookin.work
  8. //
  9. #import "LKS_PerspectiveManager.h"
  10. #import "LKS_PerspectiveViewController.h"
  11. #import "UIViewController+LookinServer.h"
  12. #import "LookinHierarchyInfo.h"
  13. #import "LookinServerDefines.h"
  14. #import "LKS_PerspectiveToolbarButtons.h"
  15. @interface LKS_PerspectiveLoadingMaskView : UIView
  16. @property(nonatomic, strong) UIView *tipsView;
  17. @property(nonatomic, strong) UILabel *firstLabel;
  18. @property(nonatomic, strong) UILabel *secondLabel;
  19. @end
  20. @implementation LKS_PerspectiveLoadingMaskView
  21. - (instancetype)initWithFrame:(CGRect)frame {
  22. if (self = [super initWithFrame:frame]) {
  23. self.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:.35];
  24. self.layer.lks_isLookinPrivateLayer = YES;
  25. self.layer.lks_avoidCapturing = YES;
  26. self.tipsView = [UIView new];
  27. self.tipsView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:.88];
  28. self.tipsView.layer.cornerRadius = 6;
  29. self.tipsView.layer.masksToBounds = YES;
  30. [self addSubview:self.tipsView];
  31. self.firstLabel = [UILabel new];
  32. self.firstLabel.text = LKS_Localized(@"Building…");
  33. self.firstLabel.textColor = [UIColor whiteColor];
  34. self.firstLabel.font = [UIFont boldSystemFontOfSize:14];
  35. self.firstLabel.textAlignment = NSTextAlignmentCenter;
  36. [self.tipsView addSubview:self.firstLabel];
  37. self.secondLabel = [UILabel new];
  38. self.secondLabel.numberOfLines = 0;
  39. self.secondLabel.textAlignment = NSTextAlignmentCenter;
  40. self.secondLabel.text = LKS_Localized(@"May take 8 or more seconds according to the UI complexity.");
  41. self.secondLabel.textColor = [UIColor colorWithRed:173/255.0 green:180/255.0 blue:190/255.0 alpha:1];
  42. self.secondLabel.font = [UIFont systemFontOfSize:12];
  43. self.secondLabel.textAlignment = NSTextAlignmentLeft;
  44. [self.tipsView addSubview:self.secondLabel];
  45. }
  46. return self;
  47. }
  48. - (void)layoutSubviews {
  49. [super layoutSubviews];
  50. UIEdgeInsets insets = UIEdgeInsetsMake(8, 10, 8, 10);
  51. CGFloat maxLabelWidth = self.bounds.size.width * .8 - insets.left - insets.right;
  52. CGSize firstSize = [self.firstLabel sizeThatFits:CGSizeMake(maxLabelWidth, CGFLOAT_MAX)];
  53. CGSize secondSize = [self.secondLabel sizeThatFits:CGSizeMake(maxLabelWidth, CGFLOAT_MAX)];
  54. CGFloat tipsWidth = MAX(firstSize.width, secondSize.width) + insets.left + insets.right;
  55. self.firstLabel.frame = CGRectMake(tipsWidth / 2.0 - firstSize.width / 2.0, insets.top, firstSize.width, firstSize.height);
  56. self.secondLabel.frame = CGRectMake(tipsWidth / 2.0 - secondSize.width / 2.0, CGRectGetMaxY(self.firstLabel.frame) + 7, secondSize.width, secondSize.height);
  57. self.tipsView.frame = ({
  58. CGFloat height = CGRectGetMaxY(self.secondLabel.frame) + insets.bottom;
  59. CGRectMake(self.bounds.size.width / 2.0 - tipsWidth / 2.0, self.bounds.size.height / 2.0 - height / 2.0, tipsWidth, height);
  60. });
  61. }
  62. @end
  63. @implementation LKS_PerspectiveContainerWindow
  64. @end
  65. @interface LKS_PerspectiveManager ()
  66. @property(nonatomic, strong) LKS_PerspectiveLoadingMaskView *loadingView;
  67. @property(nonatomic, weak) UIWindow *previousKeyWindow;
  68. @property(nonatomic, strong) LKS_PerspectiveContainerWindow *contentWindow;
  69. @property(nonatomic, strong) LKS_PerspectiveViewController *viewController;
  70. @end
  71. @implementation LKS_PerspectiveManager
  72. + (instancetype)sharedInstance {
  73. static dispatch_once_t onceToken;
  74. static LKS_PerspectiveManager *instance = nil;
  75. dispatch_once(&onceToken,^{
  76. instance = [[super allocWithZone:NULL] init];
  77. });
  78. return instance;
  79. }
  80. + (id)allocWithZone:(struct _NSZone *)zone{
  81. return [self sharedInstance];
  82. }
  83. - (void)showWithIncludedWindows:(NSArray<UIWindow *> *)includedWindows excludedWindows:(NSArray<UIWindow *> *)excludedWindows {
  84. UIViewController *visibleVc = [UIViewController lks_visibleViewController];
  85. if (!visibleVc) {
  86. NSLog(@"LookinServer - Failed to start inspecting in 3D because we didn't find any visible view controller.");
  87. return;
  88. }
  89. [[NSNotificationCenter defaultCenter] postNotificationName:@"Lookin_WillEnter3D" object:nil];
  90. if (!self.loadingView) {
  91. self.loadingView = [LKS_PerspectiveLoadingMaskView new];
  92. }
  93. [visibleVc.view.window addSubview:self.loadingView];
  94. self.loadingView.frame = visibleVc.view.window.bounds;
  95. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  96. LookinHierarchyInfo *info = [LookinHierarchyInfo perspectiveInfoWithIncludedWindows:includedWindows excludedWindows:excludedWindows];
  97. [self.loadingView removeFromSuperview];
  98. self.loadingView = nil;
  99. self.contentWindow = [LKS_PerspectiveContainerWindow new];
  100. self.contentWindow.windowLevel = UIWindowLevelAlert - 2;
  101. self.contentWindow.backgroundColor = [UIColor clearColor];
  102. self.viewController = [[LKS_PerspectiveViewController alloc] initWithHierarchyInfo:info];
  103. self.contentWindow.rootViewController = self.viewController;
  104. self.previousKeyWindow = [UIApplication sharedApplication].keyWindow;
  105. [self.contentWindow makeKeyAndVisible];
  106. [self.viewController.closeButton addTarget:self action:@selector(_exit) forControlEvents:UIControlEventTouchUpInside];
  107. });
  108. }
  109. - (void)_exit {
  110. if (!self.contentWindow) {
  111. return;
  112. }
  113. if ([[UIApplication sharedApplication] keyWindow] == self.contentWindow) {
  114. if (self.previousKeyWindow.hidden) {
  115. [[UIApplication sharedApplication].delegate.window makeKeyWindow];
  116. } else {
  117. [self.previousKeyWindow makeKeyWindow];
  118. }
  119. }
  120. self.contentWindow.hidden = YES;
  121. self.contentWindow = nil;
  122. self.viewController = nil;
  123. self.previousKeyWindow = nil;
  124. [[NSNotificationCenter defaultCenter] postNotificationName:@"Lookin_DidExit3D" object:nil];
  125. }
  126. @end
  127. #endif /* SHOULD_COMPILE_LOOKIN_SERVER */