Skip to content

Commit

Permalink
Refactored cancellation dialog feature
Browse files Browse the repository at this point in the history
  • Loading branch information
TimOliver committed Dec 1, 2018
1 parent 1402606 commit 626571c
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 92 deletions.
10 changes: 9 additions & 1 deletion Objective-C/TOCropViewController/TOCropViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,15 @@
@property (nullable, nonatomic, copy) NSString *cancelButtonTitle;

/**
If true, a custom aspect ratio is set, and the aspectRatioLockEnabled is set to YES, the crop box will swap it's dimensions depending on portrait or landscape sized images. This value also controls whether the dimensions can swap when the image is rotated.
Shows a confirmation dialog when the user hits 'Cancel' and there are pending changes.
(Default is NO)
*/
@property (nonatomic, assign) BOOL showCancelConfirmationDialog;

/**
If true, a custom aspect ratio is set, and the aspectRatioLockEnabled is set to YES, the crop box
will swap it's dimensions depending on portrait or landscape sized images.
This value also controls whether the dimensions can swap when the image is rotated.
Default is NO.
*/
Expand Down
94 changes: 29 additions & 65 deletions Objective-C/TOCropViewController/TOCropViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -880,73 +880,37 @@ - (void)dismissAnimatedFromParentViewController:(UIViewController *)viewControll
#pragma mark - Button Feedback -
- (void)cancelButtonTapped
{
// show a 'Discard Changes?' confirmation alert when user tap cancel after making changes

CGRect cropFrame = self.cropView.imageCropFrame;

BOOL angleChanged = [self.cropView angleChanged];
BOOL cropFrameChanged = NO;

// The initial image width / height when first appear in the crop view
NSInteger initialImageWidth = (NSInteger) (cropFrame.size.width);
NSInteger initialImageHeight = (NSInteger) (cropFrame.size.height);

// If the image is rotated four times (a circle back to original), the width and height are supposed to equal to originals,
// but weirdly there's seems to have ~2 pixels of error
NSInteger tolerance = 2;

// if the angle is not 0, 180, 360.. etc, swap the width and height for the image
if (self.angle % 180 != 0) {
initialImageWidth = (NSInteger) floor(cropFrame.size.height);
initialImageHeight = (NSInteger) floor(cropFrame.size.width);
}

if ((NSInteger) (floor(cropFrame.origin.x)) != 0 || (NSInteger) (floor(cropFrame.origin.y)) != 0) {
cropFrameChanged = YES;
} else if (labs(initialImageWidth - (NSInteger) floor(self.image.size.width)) > tolerance || labs(initialImageHeight - (NSInteger) floor(self.image.size.height)) > tolerance){
cropFrameChanged = YES;
}

if (angleChanged || cropFrameChanged) {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Discard Changes?" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
// Get the resource bundle depending on the framework/dependency manager we're using
NSBundle *resourceBundle = TO_CROP_VIEW_RESOURCE_BUNDLE_FOR_OBJECT(self);
NSString *yesButtonTitle = NSLocalizedStringFromTableInBundle(@"Yes", @"TOCropViewControllerLocalizable", resourceBundle, nil);
NSString *noButtonTitle = NSLocalizedStringFromTableInBundle(@"No", @"TOCropViewControllerLocalizable", resourceBundle, nil);

__weak typeof (self) weakSelf = self;
[alertController addAction:[UIAlertAction actionWithTitle:yesButtonTitle style:UIAlertActionStyleDestructive handler: ^(UIAlertAction * _Nonnull action) {
typeof (self) strongSelf = weakSelf;
bool isDelegateOrCallbackHandled = NO;

// Check if the delegate method was implemented and call if so
if ([strongSelf.delegate respondsToSelector:@selector(cropViewController:didFinishCancelled:)]) {
[strongSelf.delegate cropViewController:self didFinishCancelled:YES];
isDelegateOrCallbackHandled = YES;
}

// Check if the block version was implemented and call if so
if (strongSelf.onDidFinishCancelled != nil) {
strongSelf.onDidFinishCancelled(YES);
isDelegateOrCallbackHandled = YES;
}

// If neither callbacks were implemented, perform a default dismissing animation
if (!isDelegateOrCallbackHandled) {
if (strongSelf.navigationController) {
[strongSelf.navigationController popViewControllerAnimated:YES];
}
else {
strongSelf.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[strongSelf.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
}
}]];
[alertController addAction:[UIAlertAction actionWithTitle:noButtonTitle style:UIAlertActionStyleCancel handler:nil]];
[self presentViewController:alertController animated:YES completion: nil];
if (!self.cropView.canBeReset || !self.showCancelConfirmationDialog) {
[self dismissCropViewController];
return;
}


// Get the resource bundle depending on the framework/dependency manager we're using
NSBundle *resourceBundle = TO_CROP_VIEW_RESOURCE_BUNDLE_FOR_OBJECT(self);

NSString *title = NSLocalizedStringFromTableInBundle(@"Delete Changes?", @"TOCropViewControllerLocalizable", resourceBundle, nil);
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];


NSString *yesButtonTitle = NSLocalizedStringFromTableInBundle(@"Yes", @"TOCropViewControllerLocalizable", resourceBundle, nil);
NSString *noButtonTitle = NSLocalizedStringFromTableInBundle(@"No", @"TOCropViewControllerLocalizable", resourceBundle, nil);

__weak typeof (self) weakSelf = self;
UIAlertAction *yesAction = [UIAlertAction actionWithTitle:yesButtonTitle style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
[weakSelf dismissCropViewController];
}];
[alertController addAction:yesAction];

UIAlertAction *noAction = [UIAlertAction actionWithTitle:noButtonTitle style:UIAlertActionStyleCancel handler:nil];
[alertController addAction:noAction];

[weakSelf presentViewController:alertController animated:YES completion: nil];
}

- (void)dismissCropViewController
{
bool isDelegateOrCallbackHandled = NO;

// Check if the delegate method was implemented and call if so
Expand Down
6 changes: 0 additions & 6 deletions Objective-C/TOCropViewController/Views/TOCropView.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,6 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (nonatomic, assign) NSInteger angle;


/**
True if the original angle set before the crop view is shown doesn't equal to the latest angle
*/
@property (nonatomic, readonly) BOOL angleChanged;

/**
Hide all of the crop elements for transition animations
*/
Expand Down
20 changes: 0 additions & 20 deletions Objective-C/TOCropViewController/Views/TOCropView.m
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,6 @@ @interface TOCropView () <UIScrollViewDelegate, UIGestureRecognizerDelegate>
@property (nonatomic, assign) NSInteger restoreAngle;
@property (nonatomic, assign) CGRect restoreImageCropFrame;

/* Angle set on the crop view before it was presented */
@property (nonatomic, assign) NSInteger initialAngle;

/* Set to YES once `performInitialLayout` is called. This lets pending properties get queued until the view
has been properly set up in its parent. */
@property (nonatomic, assign) BOOL initialSetupPerformed;
Expand Down Expand Up @@ -151,7 +148,6 @@ - (void)setup
self.resetAspectRatioEnabled = !circularMode;
self.restoreImageCropFrame = CGRectZero;
self.restoreAngle = 0;
self.initialAngle = 0;
self.cropAdjustingDelay = kTOCropTimerDuration;
self.cropViewPadding = kTOCropViewPadding;
self.maximumZoomScale = kTOMaximumZoomScale;
Expand Down Expand Up @@ -1202,21 +1198,6 @@ - (void)setCanBeReset:(BOOL)canReset
}
}

- (BOOL)angleChanged {
NSInteger tmpAngle = self.angle;
NSInteger tmpInitialAngle = self.initialAngle;

if (tmpAngle < 0) {
tmpAngle += 360;
}

if (tmpInitialAngle < 0) {
tmpInitialAngle += 360;
}

return tmpAngle % 360 != tmpInitialAngle % 360;
}

- (void)setAngle:(NSInteger)angle
{
//The initial layout would not have been performed yet.
Expand All @@ -1227,7 +1208,6 @@ - (void)setAngle:(NSInteger)angle
}

if (!self.initialSetupPerformed) {
self.initialAngle = newAngle;
self.restoreAngle = newAngle;
return;
}
Expand Down

0 comments on commit 626571c

Please sign in to comment.