FrozenFramesViewController.m 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. // Copyright 2020 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // Non-google3 relative import to support building with Xcode.
  15. #import "FrozenFramesViewController.h"
  16. /** Edge insets used by internal subviews. */
  17. static const CGFloat kEdgeInsetsTop = 10.0f;
  18. static const CGFloat kEdgeInsetsBottom = 10.0f;
  19. static const CGFloat kEdgeInsetsLeft = 20.0f;
  20. static const CGFloat kEdgeInsetsRight = 20.0f;
  21. @interface FrozenFramesViewController ()
  22. /** The activity indicator that is being animated on screen. */
  23. @property(nonatomic, weak) UIActivityIndicatorView *activityIndicator;
  24. /** The button whose action causes the main thread to sleep for 5 seconds. */
  25. @property(nonatomic, weak) UIButton *freezeButton;
  26. @end
  27. @implementation FrozenFramesViewController
  28. #pragma mark - View Life Cycle
  29. - (void)loadView {
  30. UIView *view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  31. view.backgroundColor = [UIColor darkGrayColor];
  32. self.view = view;
  33. [self createViewTree];
  34. [self constrainViews];
  35. }
  36. - (void)viewWillAppear:(BOOL)animated {
  37. [self.activityIndicator startAnimating];
  38. }
  39. - (void)viewWillDisappear:(BOOL)animated {
  40. [self.activityIndicator stopAnimating];
  41. }
  42. #pragma mark - Private methods
  43. /** Creates and adds the necessary subviews. */
  44. - (void)createViewTree {
  45. [self addActivityIndicator];
  46. [self addFreezeButton];
  47. }
  48. /** Adds NSLayoutConstraints to the activity indicator. */
  49. - (void)constrainActivityIndicator {
  50. NSArray *horizontalConstraints = [[NSLayoutConstraint
  51. constraintsWithVisualFormat:@"H:|-(>=20)-[_activityIndicator]-(>=20)-|"
  52. options:0
  53. metrics:nil
  54. views:NSDictionaryOfVariableBindings(_activityIndicator)]
  55. arrayByAddingObject:[NSLayoutConstraint constraintWithItem:_activityIndicator
  56. attribute:NSLayoutAttributeCenterX
  57. relatedBy:NSLayoutRelationEqual
  58. toItem:self.view
  59. attribute:NSLayoutAttributeCenterX
  60. multiplier:1.f
  61. constant:0.f]];
  62. NSArray *verticalConstraints = [[NSLayoutConstraint
  63. constraintsWithVisualFormat:@"V:|-(>=20)-[_activityIndicator]-(>=20)-|"
  64. options:0
  65. metrics:nil
  66. views:NSDictionaryOfVariableBindings(_activityIndicator)]
  67. arrayByAddingObject:[NSLayoutConstraint constraintWithItem:_activityIndicator
  68. attribute:NSLayoutAttributeCenterY
  69. relatedBy:NSLayoutRelationEqual
  70. toItem:self.view
  71. attribute:NSLayoutAttributeCenterY
  72. multiplier:1.f
  73. constant:0.f]];
  74. [self.view addConstraints:horizontalConstraints];
  75. [self.view addConstraints:verticalConstraints];
  76. }
  77. /** Adds NSLayoutConstraints to the freezeButton. */
  78. - (void)constrainButton {
  79. NSArray *horizontalConstraints = [[NSLayoutConstraint
  80. constraintsWithVisualFormat:@"H:|-(>=20)-[_freezeButton]-(>=20)-|"
  81. options:0
  82. metrics:nil
  83. views:NSDictionaryOfVariableBindings(_freezeButton)]
  84. arrayByAddingObject:[NSLayoutConstraint constraintWithItem:_freezeButton
  85. attribute:NSLayoutAttributeCenterX
  86. relatedBy:NSLayoutRelationEqual
  87. toItem:self.view
  88. attribute:NSLayoutAttributeCenterX
  89. multiplier:1.f
  90. constant:0.f]];
  91. NSArray *verticalConstraints = [NSLayoutConstraint
  92. constraintsWithVisualFormat:@"V:[_freezeButton]-100-|"
  93. options:0
  94. metrics:nil
  95. views:NSDictionaryOfVariableBindings(_freezeButton)];
  96. [self.view addConstraints:horizontalConstraints];
  97. [self.view addConstraints:verticalConstraints];
  98. }
  99. /** Calls all the methods that add the necessary constraints for the views on screen. */
  100. - (void)constrainViews {
  101. [self constrainButton];
  102. [self constrainActivityIndicator];
  103. }
  104. /** Sets up and adds the activity indicator as a subview of the root view. */
  105. - (void)addActivityIndicator {
  106. UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc]
  107. initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
  108. activityIndicator.translatesAutoresizingMaskIntoConstraints = NO;
  109. activityIndicator.alpha = 1.0;
  110. self.activityIndicator = activityIndicator;
  111. [self.view addSubview:activityIndicator];
  112. }
  113. /** Sets up and adds the freezeButton as a subview of the root view. */
  114. - (void)addFreezeButton {
  115. UIButton *freezeButton = [[UIButton alloc] init];
  116. freezeButton.translatesAutoresizingMaskIntoConstraints = NO;
  117. [freezeButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
  118. freezeButton.backgroundColor = [UIColor whiteColor];
  119. [freezeButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateDisabled];
  120. freezeButton.titleLabel.font = [UIFont systemFontOfSize:12.0];
  121. freezeButton.contentEdgeInsets =
  122. UIEdgeInsetsMake(kEdgeInsetsTop, kEdgeInsetsLeft, kEdgeInsetsBottom, kEdgeInsetsRight);
  123. freezeButton.layer.cornerRadius = 3.0f;
  124. freezeButton.layer.borderColor = [[UIColor blackColor] CGColor];
  125. freezeButton.layer.borderWidth = 1.0f;
  126. [freezeButton setTitle:@"Stall the main thread for 5 seconds" forState:UIControlStateNormal];
  127. [freezeButton addTarget:self
  128. action:@selector(stallMainThread)
  129. forControlEvents:UIControlEventTouchDown];
  130. self.freezeButton = freezeButton;
  131. [self.view addSubview:freezeButton];
  132. }
  133. /** Stalls the main thread for 5 seconds. */
  134. - (void)stallMainThread {
  135. dispatch_async(dispatch_get_main_queue(), ^{
  136. [NSThread sleepForTimeInterval:5];
  137. });
  138. }
  139. @end