Skip to content

Commit 7dcec5d

Browse files
authored
Merge pull request #320 from TimOliver/refactor-allowed-aspect-ratios
Refactored allowed aspect ratios
2 parents 84f995a + 8eb8ae2 commit 7dcec5d

File tree

3 files changed

+56
-124
lines changed

3 files changed

+56
-124
lines changed

Objective-C/TOCropViewController/TOCropViewController.h

+15-6
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@
4242
@param cropRect A rectangle indicating the crop region of the image the user chose (In the original image's local co-ordinate space)
4343
@param angle The angle of the image when it was cropped
4444
*/
45-
- (void)cropViewController:(nonnull TOCropViewController *)cropViewController didCropImageToRect:(CGRect)cropRect angle:(NSInteger)angle NS_SWIFT_NAME(cropViewController(_:didCropImageToRect:angle:));
45+
- (void)cropViewController:(nonnull TOCropViewController *)cropViewController
46+
didCropImageToRect:(CGRect)cropRect
47+
angle:(NSInteger)angle;
4648

4749
/**
4850
Called when the user has committed the crop action, and provides
@@ -52,7 +54,9 @@
5254
@param cropRect A rectangle indicating the crop region of the image the user chose (In the original image's local co-ordinate space)
5355
@param angle The angle of the image when it was cropped
5456
*/
55-
- (void)cropViewController:(nonnull TOCropViewController *)cropViewController didCropToImage:(nonnull UIImage *)image withRect:(CGRect)cropRect angle:(NSInteger)angle NS_SWIFT_NAME(cropViewController(_:didCropToImage:rect:angle:));
57+
- (void)cropViewController:(nonnull TOCropViewController *)cropViewController
58+
didCropToImage:(nonnull UIImage *)image withRect:(CGRect)cropRect
59+
angle:(NSInteger)angle;
5660

5761
/**
5862
If the cropping style is set to circular, implementing this delegate will return a circle-cropped version of the selected
@@ -62,7 +66,9 @@
6266
@param cropRect A rectangle indicating the crop region of the image the user chose (In the original image's local co-ordinate space)
6367
@param angle The angle of the image when it was cropped
6468
*/
65-
- (void)cropViewController:(nonnull TOCropViewController *)cropViewController didCropToCircularImage:(nonnull UIImage *)image withRect:(CGRect)cropRect angle:(NSInteger)angle NS_SWIFT_NAME(cropViewController(_:didCropToCircleImage:rect:angle:));
69+
- (void)cropViewController:(nonnull TOCropViewController *)cropViewController
70+
didCropToCircularImage:(nonnull UIImage *)image withRect:(CGRect)cropRect
71+
angle:(NSInteger)angle;
6672

6773
/**
6874
If implemented, when the user hits cancel, or completes a
@@ -72,7 +78,8 @@
7278
@param cancelled Whether a cropping action was actually performed, or if the user explicitly hit 'Cancel'
7379
7480
*/
75-
- (void)cropViewController:(nonnull TOCropViewController *)cropViewController didFinishCancelled:(BOOL)cancelled NS_SWIFT_NAME(cropViewController(_:didFinishCancelled:));
81+
- (void)cropViewController:(nonnull TOCropViewController *)cropViewController
82+
didFinishCancelled:(BOOL)cancelled;
7683

7784
@end
7885

@@ -258,9 +265,11 @@
258265
@property (nullable, nonatomic, strong) NSArray<UIActivityType> *excludedActivityTypes;
259266

260267
/**
261-
The aspect ratios which user can select in the actionsheet
268+
An array of `TOCropViewControllerAspectRatioPreset` enum values denoting which
269+
aspect ratios the crop view controller may display (Default is nil. All are shown)
262270
*/
263-
@property (nullable, nonatomic, strong) NSArray <NSNumber *> *allowedAspectRatios;
271+
@property (nullable, nonatomic, strong) NSArray<NSNumber *> *allowedAspectRatios;
272+
264273
/**
265274
When the user hits cancel, or completes a
266275
UIActivityViewController operation, this block will be called,

Objective-C/TOCropViewController/TOCropViewController.m

+40-117
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,6 @@ - (instancetype)initWithCroppingStyle:(TOCropViewCroppingStyle)style image:(UIIm
9999
// Default initial behaviour
100100
_aspectRatioPreset = TOCropViewControllerAspectRatioPresetOriginal;
101101
_toolbarPosition = TOCropViewControllerToolbarPositionBottom;
102-
103-
_allowedAspectRatios = @[@(TOCropViewControllerAspectRatioPresetOriginal),
104-
@(TOCropViewControllerAspectRatioPresetSquare),
105-
@(TOCropViewControllerAspectRatioPreset3x2),
106-
@(TOCropViewControllerAspectRatioPreset5x3),
107-
@(TOCropViewControllerAspectRatioPreset4x3),
108-
@(TOCropViewControllerAspectRatioPreset5x4),
109-
@(TOCropViewControllerAspectRatioPreset7x5),
110-
@(TOCropViewControllerAspectRatioPreset16x9)];
111102
}
112103

113104
return self;
@@ -592,77 +583,47 @@ - (void)showAspectRatioDialog
592583
//Prepare the list that will be fed to the alert view/controller
593584

594585
// Ratio titles according to the order of enum TOCropViewControllerAspectRatioPreset
595-
NSArray *portraitRatioTitles = @[originalButtonTitle, squareButtonTitle, @"2:3", @"3:5", @"3:4", @"4:5", @"5:7", @"9:16"];
596-
NSArray *landscapeRatioTitles = @[originalButtonTitle, squareButtonTitle, @"3:2", @"5:3", @"4:3", @"5:4", @"7:5", @"16:9"];
597-
598-
NSMutableArray *items = [NSMutableArray array];
599-
if (verticalCropBox) {
600-
for(NSNumber *aspectRatio in _allowedAspectRatios){
601-
NSInteger index = [aspectRatio integerValue];
602-
[items addObject:portraitRatioTitles[index]];
586+
NSArray<NSString *> *portraitRatioTitles = @[originalButtonTitle, squareButtonTitle, @"2:3", @"3:5", @"3:4", @"4:5", @"5:7", @"9:16"];
587+
NSArray<NSString *> *landscapeRatioTitles = @[originalButtonTitle, squareButtonTitle, @"3:2", @"5:3", @"4:3", @"5:4", @"7:5", @"16:9"];
588+
589+
NSMutableArray *ratioValues = [NSMutableArray array];
590+
NSMutableArray *itemStrings = [NSMutableArray array];
591+
592+
if (self.allowedAspectRatios == nil) {
593+
for (NSInteger i = 0; i < TOCropViewControllerAspectRatioPresetCustom; i++) {
594+
NSString *itemTitle = verticalCropBox ? portraitRatioTitles[i] : landscapeRatioTitles[i];
595+
[itemStrings addObject:itemTitle];
596+
[ratioValues addObject:@(i)];
603597
}
604598
}
605599
else {
606-
for(NSNumber *aspectRatio in _allowedAspectRatios){
607-
NSInteger index = [aspectRatio integerValue];
608-
[items addObject:landscapeRatioTitles[index]];
609-
}
610-
}
611-
612-
//Present via a UIAlertController if >= iOS 8
613-
if (NSClassFromString(@"UIAlertController")) {
614-
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
615-
[alertController addAction:[UIAlertAction actionWithTitle:cancelButtonTitle style:UIAlertActionStyleCancel handler:nil]];
616-
617-
//Add each item to the alert controller
618-
NSInteger i = 0;
619-
for(NSNumber *aspectRatio in _allowedAspectRatios){
620-
UIAlertAction *action = [UIAlertAction actionWithTitle:items[i] style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
621-
[self setAspectRatioPreset:(TOCropViewControllerAspectRatioPreset)[aspectRatio integerValue] animated:YES];
622-
self.aspectRatioLockEnabled = YES;
623-
}];
624-
[alertController addAction:action];
625-
i++;
600+
for (NSNumber *allowedRatio in self.allowedAspectRatios) {
601+
TOCropViewControllerAspectRatioPreset ratio = allowedRatio.integerValue;
602+
NSString *itemTitle = verticalCropBox ? portraitRatioTitles[ratio] : landscapeRatioTitles[ratio];
603+
[itemStrings addObject:itemTitle];
604+
[ratioValues addObject:allowedRatio];
626605
}
627-
628-
alertController.modalPresentationStyle = UIModalPresentationPopover;
629-
UIPopoverPresentationController *presentationController = [alertController popoverPresentationController];
630-
presentationController.sourceView = self.toolbar;
631-
presentationController.sourceRect = self.toolbar.clampButtonFrame;
632-
[self presentViewController:alertController animated:YES completion:nil];
633606
}
634-
else {
635-
636-
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0
637-
//TODO: Completely overhaul this once iOS 7 support is dropped
638-
#pragma clang diagnostic push
639-
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
640-
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil
641-
delegate:self
642-
cancelButtonTitle:cancelButtonTitle
643-
destructiveButtonTitle:nil
644-
otherButtonTitles:nil];
645-
646-
for (NSString *item in items) {
647-
[actionSheet addButtonWithTitle:item];
648-
}
649-
650-
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
651-
[actionSheet showFromRect:self.toolbar.clampButtonFrame inView:self.toolbar animated:YES];
652-
else
653-
[actionSheet showInView:self.view];
654-
#pragma clang diagnostic pop
655-
#endif
607+
608+
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
609+
[alertController addAction:[UIAlertAction actionWithTitle:cancelButtonTitle style:UIAlertActionStyleCancel handler:nil]];
610+
611+
//Add each item to the alert controller
612+
for (NSInteger i = 0; i < itemStrings.count; i++) {
613+
id handlerBlock = ^(UIAlertAction *action) {
614+
[self setAspectRatioPreset:[ratioValues[i] integerValue] animated:YES];
615+
self.aspectRatioLockEnabled = YES;
616+
};
617+
UIAlertAction *action = [UIAlertAction actionWithTitle:itemStrings[i] style:UIAlertActionStyleDefault handler:handlerBlock];
618+
[alertController addAction:action];
656619
}
657-
}
658620

659-
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0
660-
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
661-
{
662-
[self setAspectRatioPreset:(TOCropViewControllerAspectRatioPreset)buttonIndex animated:YES];
663-
self.aspectRatioLockEnabled = YES;
621+
alertController.modalPresentationStyle = UIModalPresentationPopover;
622+
UIPopoverPresentationController *presentationController = [alertController popoverPresentationController];
623+
presentationController.sourceView = self.toolbar;
624+
presentationController.sourceRect = self.toolbar.clampButtonFrame;
625+
[self presentViewController:alertController animated:YES completion:nil];
664626
}
665-
#endif
666627

667628
- (void)setAspectRatioPreset:(TOCropViewControllerAspectRatioPreset)aspectRatioPreset animated:(BOOL)animated
668629
{
@@ -954,28 +915,14 @@ - (void)doneButtonTapped
954915

955916
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:self.applicationActivities];
956917
activityController.excludedActivityTypes = self.excludedActivityTypes;
957-
958-
if (NSClassFromString(@"UIPopoverPresentationController")) {
959-
activityController.modalPresentationStyle = UIModalPresentationPopover;
960-
activityController.popoverPresentationController.sourceView = self.toolbar;
961-
activityController.popoverPresentationController.sourceRect = self.toolbar.doneButtonFrame;
962-
[self presentViewController:activityController animated:YES completion:nil];
963-
}
964-
else {
965-
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
966-
[self presentViewController:activityController animated:YES completion:nil];
967-
}
968-
else {
969-
#pragma clang diagnostic push
970-
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
971-
[self.activityPopoverController dismissPopoverAnimated:NO];
972-
self.activityPopoverController = [[UIPopoverController alloc] initWithContentViewController:activityController];
973-
[self.activityPopoverController presentPopoverFromRect:self.toolbar.doneButtonFrame inView:self.toolbar permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
974-
#pragma clang diagnostic pop
975-
}
976-
}
918+
919+
activityController.modalPresentationStyle = UIModalPresentationPopover;
920+
activityController.popoverPresentationController.sourceView = self.toolbar;
921+
activityController.popoverPresentationController.sourceRect = self.toolbar.doneButtonFrame;
922+
[self presentViewController:activityController animated:YES completion:nil];
923+
977924
__weak typeof(activityController) blockController = activityController;
978-
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0
925+
979926
activityController.completionWithItemsHandler = ^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
980927
if (!completed) {
981928
return;
@@ -997,30 +944,6 @@ - (void)doneButtonTapped
997944
blockController.completionWithItemsHandler = nil;
998945
}
999946
};
1000-
#else
1001-
activityController.completionHandler = ^(NSString *activityType, BOOL completed) {
1002-
if (!completed) {
1003-
return;
1004-
}
1005-
1006-
BOOL isCallbackOrDelegateHandled = NO;
1007-
1008-
if (self.onDidFinishCancelled != nil) {
1009-
self.onDidFinishCancelled(NO);
1010-
isCallbackOrDelegateHandled = YES;
1011-
}
1012-
1013-
if ([self.delegate respondsToSelector:@selector(cropViewController:didFinishCancelled:)]) {
1014-
[self.delegate cropViewController:self didFinishCancelled:NO];
1015-
isCallbackOrDelegateHandled = YES;
1016-
}
1017-
1018-
if (!isCallbackOrDelegateHandled) {
1019-
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
1020-
blockController.completionHandler = nil;
1021-
}
1022-
};
1023-
#endif
1024947

1025948
return;
1026949
}

Objective-C/TOCropViewControllerExample/ViewController.m

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ - (void)imagePickerController:(UIImagePickerController *)picker didFinishPicking
5454
//cropController.allowedAspectRatios = @[@(TOCropViewControllerAspectRatioPresetOriginal),
5555
// @(TOCropViewControllerAspectRatioPresetSquare),
5656
// @(TOCropViewControllerAspectRatioPreset3x2)];
57-
57+
5858
//cropController.rotateButtonsHidden = YES;
5959
//cropController.rotateClockwiseButtonHidden = NO;
6060

0 commit comments

Comments
 (0)