FLEXImagePreviewViewController.m 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. //
  2. // FLEXImagePreviewViewController.m
  3. // Flipboard
  4. //
  5. // Created by Ryan Olson on 6/12/14.
  6. // Copyright (c) 2020 FLEX Team. All rights reserved.
  7. //
  8. #import "FLEXImagePreviewViewController.h"
  9. #import "FLEXUtility.h"
  10. #import "FLEXColor.h"
  11. #import "FLEXResources.h"
  12. @interface FLEXImagePreviewViewController () <UIScrollViewDelegate>
  13. @property (nonatomic) UIImage *image;
  14. @property (nonatomic) UIScrollView *scrollView;
  15. @property (nonatomic) UIImageView *imageView;
  16. @property (nonatomic) UITapGestureRecognizer *bgColorTapGesture;
  17. @property (nonatomic) NSInteger backgroundColorIndex;
  18. @property (nonatomic, readonly) NSArray<UIColor *> *backgroundColors;
  19. @end
  20. #pragma mark -
  21. @implementation FLEXImagePreviewViewController
  22. #pragma mark Initialization
  23. + (instancetype)previewForView:(UIView *)view {
  24. #if TARGET_OS_TV
  25. return [self forImage:[FLEXUtility previewImageForLayer:view.layer]]; //for some reason the one view 'view' below literally never works on tvOS
  26. #endif
  27. return [self forImage:[FLEXUtility previewImageForView:view]];
  28. }
  29. + (instancetype)previewForLayer:(CALayer *)layer {
  30. return [self forImage:[FLEXUtility previewImageForLayer:layer]];
  31. }
  32. + (instancetype)forImage:(UIImage *)image {
  33. return [[self alloc] initWithImage:image];
  34. }
  35. - (id)initWithImage:(UIImage *)image {
  36. NSParameterAssert(image);
  37. self = [super init];
  38. if (self) {
  39. self.title = @"Preview";
  40. self.image = image;
  41. _backgroundColors = @[FLEXResources.checkerPatternColor, UIColor.whiteColor, UIColor.blackColor];
  42. }
  43. return self;
  44. }
  45. #pragma mark Lifecycle
  46. - (void)viewDidLoad {
  47. [super viewDidLoad];
  48. self.imageView = [[UIImageView alloc] initWithImage:self.image];
  49. self.scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
  50. self.scrollView.delegate = self;
  51. self.scrollView.backgroundColor = self.backgroundColors.firstObject;
  52. self.scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  53. [self.scrollView addSubview:self.imageView];
  54. self.scrollView.contentSize = self.imageView.frame.size;
  55. self.scrollView.minimumZoomScale = 1.0;
  56. self.scrollView.maximumZoomScale = 2.0;
  57. [self.view addSubview:self.scrollView];
  58. self.bgColorTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(changeBackground)];
  59. [self.scrollView addGestureRecognizer:self.bgColorTapGesture];
  60. self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
  61. initWithBarButtonSystemItem:UIBarButtonSystemItemAction
  62. target:self
  63. action:@selector(actionButtonPressed:)
  64. ];
  65. }
  66. - (void)viewDidLayoutSubviews {
  67. [self centerContentInScrollViewIfNeeded];
  68. }
  69. #pragma mark UIScrollViewDelegate
  70. - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
  71. return self.imageView;
  72. }
  73. - (void)scrollViewDidZoom:(UIScrollView *)scrollView {
  74. [self centerContentInScrollViewIfNeeded];
  75. }
  76. #pragma mark Private
  77. - (void)centerContentInScrollViewIfNeeded {
  78. CGFloat horizontalInset = 0.0;
  79. CGFloat verticalInset = 0.0;
  80. if (self.scrollView.contentSize.width < self.scrollView.bounds.size.width) {
  81. horizontalInset = (self.scrollView.bounds.size.width - self.scrollView.contentSize.width) / 2.0;
  82. }
  83. if (self.scrollView.contentSize.height < self.scrollView.bounds.size.height) {
  84. verticalInset = (self.scrollView.bounds.size.height - self.scrollView.contentSize.height) / 2.0;
  85. }
  86. self.scrollView.contentInset = UIEdgeInsetsMake(verticalInset, horizontalInset, verticalInset, horizontalInset);
  87. }
  88. - (void)changeBackground {
  89. self.backgroundColorIndex++;
  90. self.backgroundColorIndex %= self.backgroundColors.count;
  91. self.scrollView.backgroundColor = self.backgroundColors[self.backgroundColorIndex];
  92. }
  93. + (NSString *)documentsFolder {
  94. NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  95. return [paths objectAtIndex:0];
  96. }
  97. - (void)actionButtonPressed:(id)sender {
  98. #if TARGET_OS_TV
  99. if ([FLEXUtility airdropAvailable]){
  100. NSString *outputFile = [[FLEXImagePreviewViewController documentsFolder] stringByAppendingPathComponent:@"FLEXViewImage.png"];
  101. FXLog(@"exporting view image to file: %@", outputFile);
  102. NSFileManager *man = [NSFileManager defaultManager];
  103. if ([man fileExistsAtPath:outputFile]){
  104. [man removeItemAtPath:outputFile error:nil];
  105. }
  106. [UIImagePNGRepresentation(self.image) writeToFile:outputFile atomically:true];
  107. NSString *bundleID = [[NSBundle mainBundle] bundleIdentifier];
  108. NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"airdropper://%@?sender=%@", outputFile, bundleID]];
  109. [[UIApplication sharedApplication] openURL:url];
  110. return;
  111. } else {
  112. [FLEXAlert showAlert:@"Oh no" message:@"A jailbroken AppleTV is required to share files through AirDrop, sorry!" from:self];
  113. }
  114. #endif
  115. static BOOL canSaveToCameraRoll = NO, didShowWarning = NO;
  116. static dispatch_once_t onceToken;
  117. dispatch_once(&onceToken, ^{
  118. if (UIDevice.currentDevice.systemVersion.floatValue < 10) {
  119. canSaveToCameraRoll = YES;
  120. return;
  121. }
  122. NSBundle *mainBundle = NSBundle.mainBundle;
  123. if ([mainBundle.infoDictionary.allKeys containsObject:@"NSPhotoLibraryUsageDescription"]) {
  124. canSaveToCameraRoll = YES;
  125. }
  126. });
  127. #if !TARGET_OS_TV
  128. UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:@[self.image] applicationActivities:@[]];
  129. if (!canSaveToCameraRoll && !didShowWarning) {
  130. didShowWarning = YES;
  131. NSString *msg = @"Add 'NSPhotoLibraryUsageDescription' to this app's Info.plist to save images.";
  132. [FLEXAlert makeAlert:^(FLEXAlert *make) {
  133. make.title(@"Reminder").message(msg);
  134. make.button(@"OK").handler(^(NSArray<NSString *> *strings) {
  135. [self presentViewController:activityVC animated:YES completion:nil];
  136. });
  137. } showFrom:self];
  138. } else {
  139. [self presentViewController:activityVC animated:YES completion:nil];
  140. }
  141. #endif
  142. }
  143. @end