diff --git a/Classes/IDMPhotoBrowser.h b/Classes/IDMPhotoBrowser.h index 397a0d4b..02961af6 100644 --- a/Classes/IDMPhotoBrowser.h +++ b/Classes/IDMPhotoBrowser.h @@ -26,6 +26,7 @@ - (void)photoBrowser:(IDMPhotoBrowser *)photoBrowser didDismissActionSheetWithButtonIndex:(NSUInteger)buttonIndex photoIndex:(NSUInteger)photoIndex; - (IDMCaptionView *)photoBrowser:(IDMPhotoBrowser *)photoBrowser captionViewForPhotoAtIndex:(NSUInteger)index; - (void)photoBrowser:(IDMPhotoBrowser *)photoBrowser imageFailed:(NSUInteger)index imageView:(IDMTapDetectingImageView *)imageView; +- (void)photoBrowser:(IDMPhotoBrowser *)photoBrowser didLongPressAtIndex:(NSUInteger)index; @end // IDMPhotoBrowser diff --git a/Classes/IDMPhotoBrowser.m b/Classes/IDMPhotoBrowser.m index 9cd39f32..cadc20dd 100644 --- a/Classes/IDMPhotoBrowser.m +++ b/Classes/IDMPhotoBrowser.m @@ -20,59 +20,60 @@ // Private @interface IDMPhotoBrowser () { - // Data + // Data NSMutableArray *_photos; - - // Views - UIScrollView *_pagingScrollView; - + + // Views + UIScrollView *_pagingScrollView; + // Gesture UIPanGestureRecognizer *_panGesture; - - // Paging + UILongPressGestureRecognizer *_longPressGesture; + + // Paging NSMutableSet *_visiblePages, *_recycledPages; NSUInteger _pageIndexBeforeRotation; NSUInteger _currentPageIndex; - + // Buttons UIButton *_doneButton; - - // Toolbar - UIToolbar *_toolbar; - UIBarButtonItem *_previousButton, *_nextButton, *_actionButton; + + // Toolbar + UIToolbar *_toolbar; + UIBarButtonItem *_previousButton, *_nextButton, *_actionButton; UIBarButtonItem *_counterButton; UILabel *_counterLabel; - + // Actions UIActionSheet *_actionsSheet; UIActivityViewController *activityViewController; - + // Control NSTimer *_controlVisibilityTimer; - + // Appearance //UIStatusBarStyle _previousStatusBarStyle; - BOOL _statusBarOriginallyHidden; - + BOOL _statusBarOriginallyHidden; + // Present UIView *_senderViewForAnimation; - + // Misc BOOL _performingLayout; - BOOL _rotating; + BOOL _rotating; BOOL _viewIsActive; // active as in it's in the view heirarchy BOOL _autoHide; NSInteger _initalPageIndex; CGFloat _statusBarHeight; - + BOOL _isdraggingPhoto; - + CGRect _senderViewOriginalFrame; //UIImage *_backgroundScreenshot; - + UIWindow *_applicationWindow; - - // iOS 7 + + // iOS 7 UIViewController *_applicationTopViewController; int _previousModalPresentationStyle; } @@ -153,102 +154,102 @@ - (id)init { if ((self = [super init])) { // Defaults self.hidesBottomBarWhenPushed = YES; - + _currentPageIndex = 0; - _performingLayout = NO; // Reset on view did appear - _rotating = NO; + _performingLayout = NO; // Reset on view did appear + _rotating = NO; _viewIsActive = NO; _visiblePages = [NSMutableSet new]; _recycledPages = [NSMutableSet new]; _photos = [NSMutableArray new]; - + _initalPageIndex = 0; _autoHide = YES; _autoHideInterface = YES; - + _displayDoneButton = YES; _doneButtonImage = nil; - + _displayToolbar = YES; _displayActionButton = YES; _displayArrowButton = YES; _displayCounterLabel = NO; - + _forceHideStatusBar = NO; _usePopAnimation = NO; - _disableVerticalSwipe = NO; - - _dismissOnTouch = NO; - + _disableVerticalSwipe = NO; + + _dismissOnTouch = NO; + _useWhiteBackgroundColor = NO; _leftArrowImage = _rightArrowImage = _leftArrowSelectedImage = _rightArrowSelectedImage = nil; - + _arrowButtonsChangePhotosAnimated = YES; - + _backgroundScaleFactor = 1.0; _animationDuration = 0.28; _senderViewForAnimation = nil; _scaleImage = nil; - + _isdraggingPhoto = NO; _statusBarHeight = 20.f; _doneButtonRightInset = 20.f; // relative to status bar and safeAreaInsets _doneButtonTopInset = 10.f; - + _doneButtonSize = CGSizeMake(55.f, 26.f); - - if ([self respondsToSelector:@selector(automaticallyAdjustsScrollViewInsets)]) { + + if ([self respondsToSelector:@selector(automaticallyAdjustsScrollViewInsets)]) { self.automaticallyAdjustsScrollViewInsets = NO; - } - + } + _applicationWindow = [[[UIApplication sharedApplication] delegate] window]; - self.modalPresentationStyle = UIModalPresentationCustom; - self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; - self.modalPresentationCapturesStatusBarAppearance = YES; - self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; - + self.modalPresentationStyle = UIModalPresentationCustom; + self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; + self.modalPresentationCapturesStatusBarAppearance = YES; + self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; + // Listen for IDMPhoto notifications [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleIDMPhotoLoadingDidEndNotification:) name:IDMPhoto_LOADING_DID_END_NOTIFICATION object:nil]; } - + return self; } - (id)initWithPhotos:(NSArray *)photosArray { if ((self = [self init])) { - _photos = [[NSMutableArray alloc] initWithArray:photosArray]; - } - return self; + _photos = [[NSMutableArray alloc] initWithArray:photosArray]; + } + return self; } - (id)initWithPhotos:(NSArray *)photosArray animatedFromView:(UIView*)view { if ((self = [self init])) { - _photos = [[NSMutableArray alloc] initWithArray:photosArray]; + _photos = [[NSMutableArray alloc] initWithArray:photosArray]; _senderViewForAnimation = view; - } - return self; + } + return self; } - (id)initWithPhotoURLs:(NSArray *)photoURLsArray { if ((self = [self init])) { NSArray *photosArray = [IDMPhoto photosWithURLs:photoURLsArray]; - _photos = [[NSMutableArray alloc] initWithArray:photosArray]; - } - return self; + _photos = [[NSMutableArray alloc] initWithArray:photosArray]; + } + return self; } - (id)initWithPhotoURLs:(NSArray *)photoURLsArray animatedFromView:(UIView*)view { if ((self = [self init])) { NSArray *photosArray = [IDMPhoto photosWithURLs:photoURLsArray]; - _photos = [[NSMutableArray alloc] initWithArray:photosArray]; + _photos = [[NSMutableArray alloc] initWithArray:photosArray]; _senderViewForAnimation = view; - } - return self; + } + return self; } - (void)dealloc { @@ -262,11 +263,11 @@ - (void)releaseAllUnderlyingPhotos { } - (void)didReceiveMemoryWarning { - // Release any cached data, images, etc that aren't in use. + // Release any cached data, images, etc that aren't in use. [self releaseAllUnderlyingPhotos]; - [_recycledPages removeAllObjects]; - - // Releases the view if it doesn't have a superview. + [_recycledPages removeAllObjects]; + + // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; } @@ -276,37 +277,37 @@ - (void)panGestureRecognized:(id)sender { // Initial Setup IDMZoomingScrollView *scrollView = [self pageDisplayedAtIndex:_currentPageIndex]; //IDMTapDetectingImageView *scrollView.photoImageView = scrollView.photoImageView; - + static float firstX, firstY; - + float viewHeight = scrollView.frame.size.height; float viewHalfHeight = viewHeight/2; - + CGPoint translatedPoint = [(UIPanGestureRecognizer*)sender translationInView:self.view]; - + // Gesture Began if ([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) { [self setControlsHidden:YES animated:YES permanent:YES]; - + firstX = [scrollView center].x; firstY = [scrollView center].y; - + _senderViewForAnimation.hidden = (_currentPageIndex == _initalPageIndex); - + _isdraggingPhoto = YES; [self setNeedsStatusBarAppearanceUpdate]; } - + translatedPoint = CGPointMake(firstX, firstY+translatedPoint.y); [scrollView setCenter:translatedPoint]; - + float newY = scrollView.center.y - viewHalfHeight; float newAlpha = 1 - fabsf(newY)/viewHeight; //abs(newY)/viewHeight * 1.8; - + self.view.opaque = YES; - + self.view.backgroundColor = [UIColor colorWithWhite:(_useWhiteBackgroundColor ? 1 : 0) alpha:newAlpha]; - + // Gesture Ended if ([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) { if(scrollView.center.y > viewHalfHeight+40 || scrollView.center.y < viewHalfHeight-40) // Automatic Dismiss View @@ -315,18 +316,18 @@ - (void)panGestureRecognized:(id)sender { [self performCloseAnimationWithScrollView:scrollView]; return; } - + CGFloat finalX = firstX, finalY; - + CGFloat windowsHeigt = [_applicationWindow frame].size.height; - + if(scrollView.center.y > viewHalfHeight+30) // swipe down finalY = windowsHeigt*2; else // swipe up finalY = -viewHalfHeight; - + CGFloat animationDuration = 0.35; - + [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:animationDuration]; [UIView setAnimationCurve:UIViewAnimationCurveEaseIn]; @@ -334,23 +335,23 @@ - (void)panGestureRecognized:(id)sender { [scrollView setCenter:CGPointMake(finalX, finalY)]; self.view.backgroundColor = [UIColor colorWithWhite:0 alpha:0]; [UIView commitAnimations]; - + [self performSelector:@selector(doneButtonPressed:) withObject:self afterDelay:animationDuration]; } else // Continue Showing View { _isdraggingPhoto = NO; [self setNeedsStatusBarAppearanceUpdate]; - + self.view.backgroundColor = [UIColor colorWithWhite:(_useWhiteBackgroundColor ? 1 : 0) alpha:1]; - + CGFloat velocityY = (.35*[(UIPanGestureRecognizer*)sender velocityInView:self.view].y); - + CGFloat finalX = firstX; CGFloat finalY = viewHalfHeight; - + CGFloat animationDuration = (ABS(velocityY)*.0002)+.2; - + [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:animationDuration]; [UIView setAnimationCurve:UIViewAnimationCurveEaseOut]; @@ -361,20 +362,30 @@ - (void)panGestureRecognized:(id)sender { } } +#pragma mark - Long Press Gesture + +- (void)longPressGestureRecognized:(UILongPressGestureRecognizer*)sender { + if (sender.state == UIGestureRecognizerStateBegan) { + if ([_delegate respondsToSelector:@selector(photoBrowser:didLongPressAtIndex:)]) { + [_delegate photoBrowser:self didLongPressAtIndex:_currentPageIndex]; + } + } +} + #pragma mark - Animation - (void)performPresentAnimation { self.view.alpha = 0.0f; _pagingScrollView.alpha = 0.0f; - + UIImage *imageFromView = _scaleImage ? _scaleImage : [self getImageFromView:_senderViewForAnimation]; - + _senderViewOriginalFrame = [_senderViewForAnimation.superview convertRect:_senderViewForAnimation.frame toView:nil]; - + UIView *fadeView = [[UIView alloc] initWithFrame:_applicationWindow.bounds]; fadeView.backgroundColor = [UIColor clearColor]; [_applicationWindow addSubview:fadeView]; - + UIImageView *resizableImageView = [[UIImageView alloc] initWithImage:imageFromView]; resizableImageView.frame = _senderViewOriginalFrame; resizableImageView.clipsToBounds = YES; @@ -387,7 +398,7 @@ - (void)performPresentAnimation { } [_applicationWindow addSubview:resizableImageView]; _senderViewForAnimation.hidden = YES; - + void (^completion)() = ^() { self.view.alpha = 1.0f; _pagingScrollView.alpha = 1.0f; @@ -395,13 +406,13 @@ - (void)performPresentAnimation { [fadeView removeFromSuperview]; [resizableImageView removeFromSuperview]; }; - + [UIView animateWithDuration:_animationDuration animations:^{ fadeView.backgroundColor = self.useWhiteBackgroundColor ? [UIColor whiteColor] : [UIColor blackColor]; } completion:nil]; - + CGRect finalImageViewFrame = [self animationFrameForImage:imageFromView presenting:YES scrollView:nil]; - + if(_usePopAnimation) { [self animateView:resizableImageView @@ -422,21 +433,21 @@ - (void)performCloseAnimationWithScrollView:(IDMZoomingScrollView*)scrollView { if ([_delegate respondsToSelector:@selector(willDisappearPhotoBrowser:)]) { [_delegate willDisappearPhotoBrowser:self]; } - + float fadeAlpha = 1 - fabs(scrollView.frame.origin.y)/scrollView.frame.size.height; - + UIImage *imageFromView = [scrollView.photo underlyingImage]; if (!imageFromView && [scrollView.photo respondsToSelector:@selector(placeholderImage)]) { imageFromView = [scrollView.photo placeholderImage]; } - + UIView *fadeView = [[UIView alloc] initWithFrame:_applicationWindow.bounds]; fadeView.backgroundColor = self.useWhiteBackgroundColor ? [UIColor whiteColor] : [UIColor blackColor]; fadeView.alpha = fadeAlpha; [_applicationWindow addSubview:fadeView]; - + CGRect imageViewFrame = [self animationFrameForImage:imageFromView presenting:NO scrollView:scrollView]; - + UIImageView *resizableImageView = [[UIImageView alloc] initWithImage:imageFromView]; resizableImageView.frame = imageViewFrame; resizableImageView.contentMode = _senderViewForAnimation ? _senderViewForAnimation.contentMode : UIViewContentModeScaleAspectFill; @@ -449,26 +460,26 @@ - (void)performCloseAnimationWithScrollView:(IDMZoomingScrollView*)scrollView { } [_applicationWindow addSubview:resizableImageView]; self.view.hidden = YES; - + void (^completion)() = ^() { _senderViewForAnimation.hidden = NO; _senderViewForAnimation = nil; _scaleImage = nil; - + [fadeView removeFromSuperview]; [resizableImageView removeFromSuperview]; - + [self prepareForClosePhotoBrowser]; [self dismissPhotoBrowserAnimated:NO]; }; - + [UIView animateWithDuration:_animationDuration animations:^{ fadeView.alpha = 0; self.view.backgroundColor = [UIColor clearColor]; } completion:nil]; - + CGRect senderViewOriginalFrame = _senderViewForAnimation.superview ? [_senderViewForAnimation.superview convertRect:_senderViewForAnimation.frame toView:nil] : _senderViewOriginalFrame; - + if(_usePopAnimation) { [self animateView:resizableImageView @@ -490,9 +501,9 @@ - (CGRect)animationFrameForImage:(UIImage *)image presenting:(BOOL)presenting sc if (!image) { return CGRectZero; } - + CGSize imageSize = image.size; - + CGRect bounds = _applicationWindow.bounds; // adjust bounds as the photo browser does if (@available(iOS 11.0, *)) { @@ -506,9 +517,9 @@ - (CGRect)animationFrameForImage:(UIImage *)image presenting:(BOOL)presenting sc } CGFloat maxWidth = CGRectGetWidth(bounds); CGFloat maxHeight = CGRectGetHeight(bounds); - + CGRect animationFrame = CGRectZero; - + CGFloat aspect = imageSize.width / imageSize.height; if (maxWidth / aspect <= maxHeight) { animationFrame.size = CGSizeMake(maxWidth, maxWidth / aspect); @@ -516,10 +527,10 @@ - (CGRect)animationFrameForImage:(UIImage *)image presenting:(BOOL)presenting sc else { animationFrame.size = CGSizeMake(maxHeight * aspect, maxHeight); } - + animationFrame.origin.x = roundf((maxWidth - animationFrame.size.width) / 2.0f); animationFrame.origin.y = roundf((maxHeight - animationFrame.size.height) / 2.0f); - + if (!presenting) { animationFrame.origin.y += scrollView.frame.origin.y; } @@ -531,27 +542,28 @@ - (CGRect)animationFrameForImage:(UIImage *)image presenting:(BOOL)presenting sc - (void)prepareForClosePhotoBrowser { // Gesture [_applicationWindow removeGestureRecognizer:_panGesture]; - + [_applicationWindow removeGestureRecognizer:_longPressGesture]; + _autoHide = NO; - + // Controls [NSObject cancelPreviousPerformRequestsWithTarget:self]; // Cancel any pending toggles from taps } - (void)dismissPhotoBrowserAnimated:(BOOL)animated { self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; - + if ([_delegate respondsToSelector:@selector(photoBrowser:willDismissAtPageIndex:)]) [_delegate photoBrowser:self willDismissAtPageIndex:_currentPageIndex]; - + [self dismissViewControllerAnimated:animated completion:^{ if ([_delegate respondsToSelector:@selector(photoBrowser:didDismissAtPageIndex:)]) [_delegate photoBrowser:self didDismissAtPageIndex:_currentPageIndex]; - -// if (SYSTEM_VERSION_LESS_THAN(@"8.0")) -// { -// _applicationTopViewController.modalPresentationStyle = _previousModalPresentationStyle; -// } + + // if (SYSTEM_VERSION_LESS_THAN(@"8.0")) + // { + // _applicationTopViewController.modalPresentationStyle = _previousModalPresentationStyle; + // } }]; } @@ -584,11 +596,11 @@ - (UIImage*)getImageFromView:(UIView *)view { - (UIViewController *)topviewController { UIViewController *topviewController = [UIApplication sharedApplication].keyWindow.rootViewController; - + while (topviewController.presentedViewController) { topviewController = topviewController.presentedViewController; } - + return topviewController; } @@ -596,27 +608,27 @@ - (UIViewController *)topviewController - (void)viewDidLoad { // View - self.view.backgroundColor = [UIColor colorWithWhite:(_useWhiteBackgroundColor ? 1 : 0) alpha:1]; - + self.view.backgroundColor = [UIColor colorWithWhite:(_useWhiteBackgroundColor ? 1 : 0) alpha:1]; + self.view.clipsToBounds = YES; - - // Setup paging scrolling view - CGRect pagingScrollViewFrame = [self frameForPagingScrollView]; - _pagingScrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame]; + + // Setup paging scrolling view + CGRect pagingScrollViewFrame = [self frameForPagingScrollView]; + _pagingScrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame]; //_pagingScrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - _pagingScrollView.pagingEnabled = YES; - _pagingScrollView.delegate = self; - _pagingScrollView.showsHorizontalScrollIndicator = NO; - _pagingScrollView.showsVerticalScrollIndicator = NO; - _pagingScrollView.backgroundColor = [UIColor clearColor]; + _pagingScrollView.pagingEnabled = YES; + _pagingScrollView.delegate = self; + _pagingScrollView.showsHorizontalScrollIndicator = NO; + _pagingScrollView.showsVerticalScrollIndicator = NO; + _pagingScrollView.backgroundColor = [UIColor clearColor]; _pagingScrollView.contentSize = [self contentSizeForPagingScrollView]; - [self.view addSubview:_pagingScrollView]; - + [self.view addSubview:_pagingScrollView]; + // Transition animation [self performPresentAnimation]; - + UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation; - + // Toolbar _toolbar = [[UIToolbar alloc] initWithFrame:[self frameForToolbarAtOrientation:currentOrientation]]; _toolbar.backgroundColor = [UIColor clearColor]; @@ -625,13 +637,13 @@ - (void)viewDidLoad { [_toolbar setBackgroundImage:[UIImage new] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault]; - + // Close Button _doneButton = [UIButton buttonWithType:UIButtonTypeCustom]; [_doneButton setFrame:[self frameForDoneButtonAtOrientation:currentOrientation]]; [_doneButton setAlpha:1.0f]; [_doneButton addTarget:self action:@selector(doneButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; - + if(!_doneButtonImage) { [_doneButton setTitleColor:[UIColor colorWithWhite:0.9 alpha:0.9] forState:UIControlStateNormal|UIControlStateHighlighted]; [_doneButton setTitle:IDMPhotoBrowserLocalizedStrings(@"Done") forState:UIControlStateNormal]; @@ -646,34 +658,34 @@ - (void)viewDidLoad { [_doneButton setImage:_doneButtonImage forState:UIControlStateNormal]; _doneButton.contentMode = UIViewContentModeScaleAspectFit; } - + UIImage *leftButtonImage = (_leftArrowImage == nil) ? [UIImage imageNamed:@"IDMPhotoBrowser.bundle/images/IDMPhotoBrowser_arrowLeft.png"] : _leftArrowImage; - + UIImage *rightButtonImage = (_rightArrowImage == nil) ? [UIImage imageNamed:@"IDMPhotoBrowser.bundle/images/IDMPhotoBrowser_arrowRight.png"] : _rightArrowImage; - + UIImage *leftButtonSelectedImage = (_leftArrowSelectedImage == nil) ? [UIImage imageNamed:@"IDMPhotoBrowser.bundle/images/IDMPhotoBrowser_arrowLeftSelected.png"] : _leftArrowSelectedImage; - + UIImage *rightButtonSelectedImage = (_rightArrowSelectedImage == nil) ? [UIImage imageNamed:@"IDMPhotoBrowser.bundle/images/IDMPhotoBrowser_arrowRightSelected.png"] : _rightArrowSelectedImage; - + // Arrows _previousButton = [[UIBarButtonItem alloc] initWithCustomView:[self customToolbarButtonImage:leftButtonImage imageSelected:leftButtonSelectedImage action:@selector(gotoPreviousPage)]]; - + _nextButton = [[UIBarButtonItem alloc] initWithCustomView:[self customToolbarButtonImage:rightButtonImage imageSelected:rightButtonSelectedImage action:@selector(gotoNextPage)]]; - + // Counter Label _counterLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 95, 40)]; _counterLabel.textAlignment = NSTextAlignmentCenter; _counterLabel.backgroundColor = [UIColor clearColor]; _counterLabel.font = [UIFont fontWithName:@"Helvetica" size:17]; - + if(_useWhiteBackgroundColor == NO) { _counterLabel.textColor = [UIColor whiteColor]; _counterLabel.shadowColor = [UIColor darkTextColor]; @@ -682,51 +694,52 @@ - (void)viewDidLoad { else { _counterLabel.textColor = [UIColor blackColor]; } - + // Counter Button _counterButton = [[UIBarButtonItem alloc] initWithCustomView:_counterLabel]; - + // Action Button if(_actionButtonImage != nil && _actionButtonSelectedImage != nil) { _actionButton = [[UIBarButtonItem alloc] initWithCustomView:[self customToolbarButtonImage:_actionButtonImage - imageSelected:_actionButtonSelectedImage - action:@selector(actionButtonPressed:)]]; + imageSelected:_actionButtonSelectedImage + action:@selector(actionButtonPressed:)]]; } else { _actionButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction - target:self - action:@selector(actionButtonPressed:)]; + target:self + action:@selector(actionButtonPressed:)]; } - + // Gesture _panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureRecognized:)]; [_panGesture setMinimumNumberOfTouches:1]; [_panGesture setMaximumNumberOfTouches:1]; - + _longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressGestureRecognized:)]; + // Update //[self reloadData]; - - // Super + + // Super [super viewDidLoad]; } - (void)viewWillAppear:(BOOL)animated { // Update [self reloadData]; - - + + if ([_delegate respondsToSelector:@selector(willAppearPhotoBrowser:)]) { [_delegate willAppearPhotoBrowser:self]; } - + // Super - [super viewWillAppear:animated]; - + [super viewWillAppear:animated]; + // Status Bar _statusBarOriginallyHidden = [UIApplication sharedApplication].statusBarHidden; - + // Update UI - [self hideControlsAfterDelay]; + [self hideControlsAfterDelay]; } - (void)viewDidAppear:(BOOL)animated { @@ -736,7 +749,7 @@ - (void)viewDidAppear:(BOOL)animated { // Release any retained subviews of the main view. - (void)viewDidUnload { - _currentPageIndex = 0; + _currentPageIndex = 0; _pagingScrollView = nil; _visiblePages = nil; _recycledPages = nil; @@ -744,7 +757,7 @@ - (void)viewDidUnload { _doneButton = nil; _previousButton = nil; _nextButton = nil; - + [super viewDidUnload]; } @@ -758,7 +771,7 @@ - (BOOL)prefersStatusBarHidden { if(_forceHideStatusBar) { return YES; } - + if(_isdraggingPhoto) { if(_statusBarOriginallyHidden) { return YES; @@ -773,52 +786,52 @@ - (BOOL)prefersStatusBarHidden { } - (UIStatusBarAnimation)preferredStatusBarUpdateAnimation { - return UIStatusBarAnimationFade; + return UIStatusBarAnimationFade; } #pragma mark - Layout - (void)viewWillLayoutSubviews { - // Flag - _performingLayout = YES; - + // Flag + _performingLayout = YES; + UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation; - + // Toolbar _toolbar.frame = [self frameForToolbarAtOrientation:currentOrientation]; - + // Done button _doneButton.frame = [self frameForDoneButtonAtOrientation:currentOrientation]; - - + + // Remember index - NSUInteger indexPriorToLayout = _currentPageIndex; - - // Get paging scroll view frame to determine if anything needs changing - CGRect pagingScrollViewFrame = [self frameForPagingScrollView]; - - // Frame needs changing - _pagingScrollView.frame = pagingScrollViewFrame; - - // Recalculate contentSize based on current orientation - _pagingScrollView.contentSize = [self contentSizeForPagingScrollView]; - - // Adjust frames and configuration of each visible page - for (IDMZoomingScrollView *page in _visiblePages) { + NSUInteger indexPriorToLayout = _currentPageIndex; + + // Get paging scroll view frame to determine if anything needs changing + CGRect pagingScrollViewFrame = [self frameForPagingScrollView]; + + // Frame needs changing + _pagingScrollView.frame = pagingScrollViewFrame; + + // Recalculate contentSize based on current orientation + _pagingScrollView.contentSize = [self contentSizeForPagingScrollView]; + + // Adjust frames and configuration of each visible page + for (IDMZoomingScrollView *page in _visiblePages) { NSUInteger index = PAGE_INDEX(page); - page.frame = [self frameForPageAtIndex:index]; + page.frame = [self frameForPageAtIndex:index]; page.captionView.frame = [self frameForCaptionView:page.captionView atIndex:index]; - [page setMaxMinZoomScalesForCurrentBounds]; - } - - // Adjust contentOffset to preserve page location based on values collected prior to location - _pagingScrollView.contentOffset = [self contentOffsetForPageAtIndex:indexPriorToLayout]; - [self didStartViewingPageAtIndex:_currentPageIndex]; // initial - - // Reset - _currentPageIndex = indexPriorToLayout; - _performingLayout = NO; - + [page setMaxMinZoomScalesForCurrentBounds]; + } + + // Adjust contentOffset to preserve page location based on values collected prior to location + _pagingScrollView.contentOffset = [self contentOffsetForPageAtIndex:indexPriorToLayout]; + [self didStartViewingPageAtIndex:_currentPageIndex]; // initial + + // Reset + _currentPageIndex = indexPriorToLayout; + _performingLayout = NO; + // Super [super viewWillLayoutSubviews]; } @@ -827,22 +840,22 @@ - (void)performLayout { // Setup _performingLayout = YES; NSUInteger numberOfPhotos = [self numberOfPhotos]; - - // Setup pages + + // Setup pages [_visiblePages removeAllObjects]; [_recycledPages removeAllObjects]; - + // Toolbar if (_displayToolbar) { [self.view addSubview:_toolbar]; } else { [_toolbar removeFromSuperview]; } - + // Close button if(_displayDoneButton && !self.navigationController.navigationBar) [self.view addSubview:_doneButton]; - + // Toolbar items & navigation UIBarButtonItem *fixedLeftSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:self action:nil]; @@ -850,38 +863,39 @@ - (void)performLayout { UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil]; NSMutableArray *items = [NSMutableArray new]; - + if (_displayActionButton) [items addObject:fixedLeftSpace]; [items addObject:flexSpace]; - + if (numberOfPhotos > 1 && _displayArrowButton) [items addObject:_previousButton]; - + if(_displayCounterLabel) { [items addObject:flexSpace]; [items addObject:_counterButton]; } - + [items addObject:flexSpace]; if (numberOfPhotos > 1 && _displayArrowButton) [items addObject:_nextButton]; [items addObject:flexSpace]; - + if(_displayActionButton) [items addObject:_actionButton]; - + [_toolbar setItems:items]; - [self updateToolbar]; - + [self updateToolbar]; + // Content offset - _pagingScrollView.contentOffset = [self contentOffsetForPageAtIndex:_currentPageIndex]; + _pagingScrollView.contentOffset = [self contentOffsetForPageAtIndex:_currentPageIndex]; [self tilePages]; _performingLayout = NO; - - if(! _disableVerticalSwipe) { - [self.view addGestureRecognizer:_panGesture]; - } + + if(! _disableVerticalSwipe) { + [self.view addGestureRecognizer:_panGesture]; + } + [self.view addGestureRecognizer:_longPressGesture]; } #pragma mark - Data @@ -889,10 +903,10 @@ - (void)performLayout { - (void)reloadData { // Get data [self releaseAllUnderlyingPhotos]; - + // Update [self performLayout]; - + // Layout [self.view setNeedsLayout]; } @@ -916,24 +930,24 @@ - (IDMCaptionView *)captionViewForPhotoAtIndex:(NSUInteger)index { } } captionView.alpha = [self areControlsHidden] ? 0 : 1; // Initial alpha - + return captionView; } - (UIImage *)imageForPhoto:(id)photo { - if (photo) { - // Get image or obtain in background - if ([photo underlyingImage]) { - return [photo underlyingImage]; - } else { + if (photo) { + // Get image or obtain in background + if ([photo underlyingImage]) { + return [photo underlyingImage]; + } else { [photo loadUnderlyingImageAndNotify]; if ([photo respondsToSelector:@selector(placeholderImage)]) { return [photo placeholderImage]; } - } - } - - return nil; + } + } + + return nil; } - (void)loadAdjacentPhotosIfNecessary:(id)photo { @@ -988,86 +1002,86 @@ - (void)handleIDMPhotoLoadingDidEndNotification:(NSNotification *)notification { #pragma mark - Paging - (void)tilePages { - // Calculate which pages should be visible - // Ignore padding as paging bounces encroach on that - // and lead to false page loads - CGRect visibleBounds = _pagingScrollView.bounds; - NSInteger iFirstIndex = (NSInteger) floorf((CGRectGetMinX(visibleBounds)+PADDING*2) / CGRectGetWidth(visibleBounds)); - NSInteger iLastIndex = (NSInteger) floorf((CGRectGetMaxX(visibleBounds)-PADDING*2-1) / CGRectGetWidth(visibleBounds)); + // Calculate which pages should be visible + // Ignore padding as paging bounces encroach on that + // and lead to false page loads + CGRect visibleBounds = _pagingScrollView.bounds; + NSInteger iFirstIndex = (NSInteger) floorf((CGRectGetMinX(visibleBounds)+PADDING*2) / CGRectGetWidth(visibleBounds)); + NSInteger iLastIndex = (NSInteger) floorf((CGRectGetMaxX(visibleBounds)-PADDING*2-1) / CGRectGetWidth(visibleBounds)); if (iFirstIndex < 0) iFirstIndex = 0; if (iFirstIndex > [self numberOfPhotos] - 1) iFirstIndex = [self numberOfPhotos] - 1; if (iLastIndex < 0) iLastIndex = 0; if (iLastIndex > [self numberOfPhotos] - 1) iLastIndex = [self numberOfPhotos] - 1; - - // Recycle no longer needed pages + + // Recycle no longer needed pages NSInteger pageIndex; - for (IDMZoomingScrollView *page in _visiblePages) { + for (IDMZoomingScrollView *page in _visiblePages) { pageIndex = PAGE_INDEX(page); - if (pageIndex < (NSUInteger)iFirstIndex || pageIndex > (NSUInteger)iLastIndex) { - [_recycledPages addObject:page]; + if (pageIndex < (NSUInteger)iFirstIndex || pageIndex > (NSUInteger)iLastIndex) { + [_recycledPages addObject:page]; [page prepareForReuse]; - [page removeFromSuperview]; - IDMLog(@"Removed page at index %i", PAGE_INDEX(page)); - } - } - [_visiblePages minusSet:_recycledPages]; + [page removeFromSuperview]; + IDMLog(@"Removed page at index %i", PAGE_INDEX(page)); + } + } + [_visiblePages minusSet:_recycledPages]; while (_recycledPages.count > 2) // Only keep 2 recycled pages [_recycledPages removeObject:[_recycledPages anyObject]]; - - // Add missing pages - for (NSUInteger index = (NSUInteger)iFirstIndex; index <= (NSUInteger)iLastIndex; index++) { - if (![self isDisplayingPageForIndex:index]) { + + // Add missing pages + for (NSUInteger index = (NSUInteger)iFirstIndex; index <= (NSUInteger)iLastIndex; index++) { + if (![self isDisplayingPageForIndex:index]) { // Add new page - IDMZoomingScrollView *page; + IDMZoomingScrollView *page; page = [[IDMZoomingScrollView alloc] initWithPhotoBrowser:self]; page.backgroundColor = [UIColor clearColor]; page.opaque = YES; - - [self configurePage:page forIndex:index]; - [_visiblePages addObject:page]; - [_pagingScrollView addSubview:page]; - IDMLog(@"Added page at index %i", index); - + + [self configurePage:page forIndex:index]; + [_visiblePages addObject:page]; + [_pagingScrollView addSubview:page]; + IDMLog(@"Added page at index %i", index); + // Add caption IDMCaptionView *captionView = [self captionViewForPhotoAtIndex:index]; captionView.frame = [self frameForCaptionView:captionView atIndex:index]; [_pagingScrollView addSubview:captionView]; page.captionView = captionView; - } - } + } + } } - (BOOL)isDisplayingPageForIndex:(NSUInteger)index { - for (IDMZoomingScrollView *page in _visiblePages) - if (PAGE_INDEX(page) == index) return YES; - return NO; + for (IDMZoomingScrollView *page in _visiblePages) + if (PAGE_INDEX(page) == index) return YES; + return NO; } - (IDMZoomingScrollView *)pageDisplayedAtIndex:(NSUInteger)index { - IDMZoomingScrollView *thePage = nil; - for (IDMZoomingScrollView *page in _visiblePages) { - if (PAGE_INDEX(page) == index) { - thePage = page; break; - } - } - return thePage; + IDMZoomingScrollView *thePage = nil; + for (IDMZoomingScrollView *page in _visiblePages) { + if (PAGE_INDEX(page) == index) { + thePage = page; break; + } + } + return thePage; } - (IDMZoomingScrollView *)pageDisplayingPhoto:(id)photo { - IDMZoomingScrollView *thePage = nil; - for (IDMZoomingScrollView *page in _visiblePages) { - if (page.photo == photo) { - thePage = page; break; - } - } - return thePage; + IDMZoomingScrollView *thePage = nil; + for (IDMZoomingScrollView *page in _visiblePages) { + if (page.photo == photo) { + thePage = page; break; + } + } + return thePage; } - (void)configurePage:(IDMZoomingScrollView *)page forIndex:(NSUInteger)index { - page.frame = [self frameForPageAtIndex:index]; + page.frame = [self frameForPageAtIndex:index]; page.tag = PAGE_INDEX_TAG_OFFSET + index; page.photo = [self photoAtIndex:index]; - + __block __weak IDMPhoto *photo = (IDMPhoto*)page.photo; __weak IDMZoomingScrollView* weakPage = page; photo.progressUpdateBlock = ^(CGFloat progress){ @@ -1076,11 +1090,11 @@ - (void)configurePage:(IDMZoomingScrollView *)page forIndex:(NSUInteger)index { } - (IDMZoomingScrollView *)dequeueRecycledPage { - IDMZoomingScrollView *page = [_recycledPages anyObject]; - if (page) { - [_recycledPages removeObject:page]; - } - return page; + IDMZoomingScrollView *page = [_recycledPages anyObject]; + if (page) { + [_recycledPages removeObject:page]; + } + return page; } // Handle page changes @@ -1126,9 +1140,9 @@ - (CGSize)contentSizeForPagingScrollView { } - (CGPoint)contentOffsetForPageAtIndex:(NSUInteger)index { - CGFloat pageWidth = _pagingScrollView.bounds.size.width; - CGFloat newOffset = index * pageWidth; - return CGPointMake(newOffset, 0); + CGFloat pageWidth = _pagingScrollView.bounds.size.width; + CGFloat newOffset = index * pageWidth; + return CGPointMake(newOffset, 0); } - (BOOL)isLandscape:(UIInterfaceOrientation)orientation @@ -1138,10 +1152,10 @@ - (BOOL)isLandscape:(UIInterfaceOrientation)orientation - (CGRect)frameForToolbarAtOrientation:(UIInterfaceOrientation)orientation { CGFloat height = 44; - + if ([self isLandscape:orientation]) height = 32; - + CGRect rtn = CGRectMake(0, self.view.bounds.size.height - height, self.view.bounds.size.width, height); rtn = [self adjustForSafeArea:rtn adjustForStatusBar:true]; return rtn; @@ -1150,7 +1164,7 @@ - (CGRect)frameForToolbarAtOrientation:(UIInterfaceOrientation)orientation { - (CGRect)frameForDoneButtonAtOrientation:(UIInterfaceOrientation)orientation { CGRect screenBound = self.view.bounds; CGFloat screenWidth = screenBound.size.width; - + CGRect rtn = CGRectMake(screenWidth - self.doneButtonRightInset - self.doneButtonSize.width, self.doneButtonTopInset, self.doneButtonSize.width, self.doneButtonSize.height); rtn = [self adjustForSafeArea:rtn adjustForStatusBar:true]; return rtn; @@ -1158,10 +1172,10 @@ - (CGRect)frameForDoneButtonAtOrientation:(UIInterfaceOrientation)orientation { - (CGRect)frameForCaptionView:(IDMCaptionView *)captionView atIndex:(NSUInteger)index { CGRect pageFrame = [self frameForPageAtIndex:index]; - + CGSize captionSize = [captionView sizeThatFits:CGSizeMake(pageFrame.size.width, 0)]; CGRect captionFrame = CGRectMake(pageFrame.origin.x, pageFrame.size.height - captionSize.height - (_toolbar.superview?_toolbar.frame.size.height:0), pageFrame.size.width, captionSize.height); - + return captionFrame; } @@ -1182,10 +1196,10 @@ - (CGRect)adjustForSafeArea:(CGRect)rect adjustForStatusBar:(BOOL)adjust forInse - (void)scrollViewDidScroll:(UIScrollView *)scrollView { // Checks if (!_viewIsActive || _performingLayout || _rotating) return; - + // Tile pages [self tilePages]; - + // Calculate current page CGRect visibleBounds = _pagingScrollView.bounds; NSInteger index = (NSInteger) (floorf(CGRectGetMidX(visibleBounds) / CGRectGetWidth(visibleBounds))); @@ -1195,44 +1209,44 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView { _currentPageIndex = index; if (_currentPageIndex != previousCurrentPage) { [self didStartViewingPageAtIndex:index]; - + if(_arrowButtonsChangePhotosAnimated) [self updateToolbar]; } } - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { - // Hide controls when dragging begins + // Hide controls when dragging begins if(_autoHideInterface){ [self setControlsHidden:YES animated:YES permanent:NO]; } } - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { - // Update toolbar when page changes - if(! _arrowButtonsChangePhotosAnimated) [self updateToolbar]; + // Update toolbar when page changes + if(! _arrowButtonsChangePhotosAnimated) [self updateToolbar]; } #pragma mark - Toolbar - (void)updateToolbar { // Counter - if ([self numberOfPhotos] > 1) { - _counterLabel.text = [NSString stringWithFormat:@"%lu %@ %lu", (unsigned long)(_currentPageIndex+1), IDMPhotoBrowserLocalizedStrings(@"of"), (unsigned long)[self numberOfPhotos]]; - } else { - _counterLabel.text = nil; - } - - // Buttons - _previousButton.enabled = (_currentPageIndex > 0); - _nextButton.enabled = (_currentPageIndex < [self numberOfPhotos]-1); + if ([self numberOfPhotos] > 1) { + _counterLabel.text = [NSString stringWithFormat:@"%lu %@ %lu", (unsigned long)(_currentPageIndex+1), IDMPhotoBrowserLocalizedStrings(@"of"), (unsigned long)[self numberOfPhotos]]; + } else { + _counterLabel.text = nil; + } + + // Buttons + _previousButton.enabled = (_currentPageIndex > 0); + _nextButton.enabled = (_currentPageIndex < [self numberOfPhotos]-1); } - (void)jumpToPageAtIndex:(NSUInteger)index { // Change page - if (index < [self numberOfPhotos]) { - CGRect pageFrame = [self frameForPageAtIndex:index]; - - if(_arrowButtonsChangePhotosAnimated) + if (index < [self numberOfPhotos]) { + CGRect pageFrame = [self frameForPageAtIndex:index]; + + if(_arrowButtonsChangePhotosAnimated) { [_pagingScrollView setContentOffset:CGPointMake(pageFrame.origin.x - PADDING, 0) animated:YES]; } @@ -1241,10 +1255,10 @@ - (void)jumpToPageAtIndex:(NSUInteger)index { _pagingScrollView.contentOffset = CGPointMake(pageFrame.origin.x - PADDING, 0); [self updateToolbar]; } - } - - // Update timer to give more time - [self hideControlsAfterDelay]; + } + + // Update timer to give more time + [self hideControlsAfterDelay]; } - (void)gotoPreviousPage { [self jumpToPageAtIndex:_currentPageIndex-1]; } @@ -1256,13 +1270,13 @@ - (void)gotoNextPage { [self jumpToPageAtIndex:_currentPageIndex+1]; } - (void)setControlsHidden:(BOOL)hidden animated:(BOOL)animated permanent:(BOOL)permanent { // Cancel any timers [self cancelControlHiding]; - + // Captions NSMutableSet *captionViews = [[NSMutableSet alloc] initWithCapacity:_visiblePages.count]; for (IDMZoomingScrollView *page in _visiblePages) { if (page.captionView) [captionViews addObject:page.captionView]; } - + // Hide/show bars [UIView animateWithDuration:(animated ? 0.1 : 0) animations:^(void) { CGFloat alpha = hidden ? 0 : 1; @@ -1271,22 +1285,22 @@ - (void)setControlsHidden:(BOOL)hidden animated:(BOOL)animated permanent:(BOOL)p [_doneButton setAlpha:alpha]; for (UIView *v in captionViews) v.alpha = alpha; } completion:^(BOOL finished) {}]; - - // Control hiding timer - // Will cancel existing timer but only begin hiding if they are visible - if (!permanent) { - [self hideControlsAfterDelay]; - } - + + // Control hiding timer + // Will cancel existing timer but only begin hiding if they are visible + if (!permanent) { + [self hideControlsAfterDelay]; + } + [self setNeedsStatusBarAppearanceUpdate]; } - (void)cancelControlHiding { - // If a timer exists then cancel and release - if (_controlVisibilityTimer) { - [_controlVisibilityTimer invalidate]; - _controlVisibilityTimer = nil; - } + // If a timer exists then cancel and release + if (_controlVisibilityTimer) { + [_controlVisibilityTimer invalidate]; + _controlVisibilityTimer = nil; + } } // Enable/disable control visiblity timer @@ -1294,28 +1308,28 @@ - (void)hideControlsAfterDelay { if (![self autoHideInterface]) { return; } - - if (![self areControlsHidden]) { + + if (![self areControlsHidden]) { [self cancelControlHiding]; - _controlVisibilityTimer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(hideControls) userInfo:nil repeats:NO]; - } + _controlVisibilityTimer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(hideControls) userInfo:nil repeats:NO]; + } } - (BOOL)areControlsHidden { - return (_toolbar.alpha == 0); + return (_toolbar.alpha == 0); } - (void)hideControls { - if(_autoHide && _autoHideInterface) { - [self setControlsHidden:YES animated:YES permanent:NO]; - } + if(_autoHide && _autoHideInterface) { + [self setControlsHidden:YES animated:YES permanent:NO]; + } } - (void)handleSingleTap { - if (_dismissOnTouch) { - [self doneButtonPressed:nil]; - } else { - [self setControlsHidden:![self areControlsHidden] animated:YES permanent:NO]; - } + if (_dismissOnTouch) { + [self doneButtonPressed:nil]; + } else { + [self setControlsHidden:![self areControlsHidden] animated:YES permanent:NO]; + } } @@ -1326,7 +1340,7 @@ - (void)setInitialPageIndex:(NSUInteger)index { if (index >= [self numberOfPhotos]) index = [self numberOfPhotos]-1; _initalPageIndex = index; _currentPageIndex = index; - if ([self isViewLoaded]) { + if ([self isViewLoaded]) { [self jumpToPageAtIndex:index]; if (!_viewIsActive) [self tilePages]; // Force tiling if view is not visible } @@ -1338,7 +1352,7 @@ - (void)doneButtonPressed:(id)sender { if ([_delegate respondsToSelector:@selector(willDisappearPhotoBrowser:)]) { [_delegate willDisappearPhotoBrowser:self]; } - + if (_senderViewForAnimation && _currentPageIndex == _initalPageIndex) { IDMZoomingScrollView *scrollView = [self pageDisplayedAtIndex:_currentPageIndex]; [self performCloseAnimationWithScrollView:scrollView]; @@ -1352,32 +1366,32 @@ - (void)doneButtonPressed:(id)sender { - (void)actionButtonPressed:(id)sender { id photo = [self photoAtIndex:_currentPageIndex]; - + if ([self numberOfPhotos] > 0 && [photo underlyingImage]) { if(!_actionButtonTitles) { // Activity view NSMutableArray *activityItems = [NSMutableArray arrayWithObject:[photo underlyingImage]]; if (photo.caption) [activityItems addObject:photo.caption]; - + self.activityViewController = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil]; - + __typeof__(self) __weak selfBlock = self; - - [self.activityViewController setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) { - [selfBlock hideControlsAfterDelay]; - selfBlock.activityViewController = nil; - }]; - - if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) { - [self presentViewController:self.activityViewController animated:YES completion:nil]; - } - else { // iPad - UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:self.activityViewController]; - [popover presentPopoverFromRect:CGRectMake(self.view.frame.size.width/2, self.view.frame.size.height/4, 0, 0) - inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny - animated:YES]; - } + + [self.activityViewController setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) { + [selfBlock hideControlsAfterDelay]; + selfBlock.activityViewController = nil; + }]; + + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) { + [self presentViewController:self.activityViewController animated:YES completion:nil]; + } + else { // iPad + UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:self.activityViewController]; + [popover presentPopoverFromRect:CGRectMake(self.view.frame.size.width/2, self.view.frame.size.height/4, 0, 0) + inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny + animated:YES]; + } } else { @@ -1387,17 +1401,17 @@ - (void)actionButtonPressed:(id)sender { for(NSString *action in _actionButtonTitles) { [self.actionsSheet addButtonWithTitle:action]; } - + self.actionsSheet.cancelButtonIndex = [self.actionsSheet addButtonWithTitle:IDMPhotoBrowserLocalizedStrings(@"Cancel")]; self.actionsSheet.actionSheetStyle = UIActionSheetStyleBlackTranslucent; - + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) { - [_actionsSheet showInView:self.view]; + [_actionsSheet showInView:self.view]; } else { [_actionsSheet showFromBarButtonItem:sender animated:YES]; } } - + // Keep controls hidden [self setControlsHidden:NO animated:YES permanent:YES]; } @@ -1408,7 +1422,7 @@ - (void)actionButtonPressed:(id)sender { - (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex { if (actionSheet == _actionsSheet) { self.actionsSheet = nil; - + if (buttonIndex != actionSheet.cancelButtonIndex) { if ([_delegate respondsToSelector:@selector(photoBrowser:didDismissActionSheetWithButtonIndex:photoIndex:)]) { [_delegate photoBrowser:self didDismissActionSheetWithButtonIndex:buttonIndex photoIndex:_currentPageIndex]; @@ -1416,7 +1430,7 @@ - (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSIn } } } - + [self hideControlsAfterDelay]; // Continue as normal... } @@ -1424,17 +1438,17 @@ - (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSIn - (void)animateView:(UIView *)view toFrame:(CGRect)frame completion:(void (^)(void))completion { - POPSpringAnimation *animation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewFrame]; - [animation setSpringBounciness:6]; - [animation setDynamicsMass:1]; + POPSpringAnimation *animation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewFrame]; + [animation setSpringBounciness:6]; + [animation setDynamicsMass:1]; [animation setToValue:[NSValue valueWithCGRect:frame]]; - [view pop_addAnimation:animation forKey:nil]; - + [view pop_addAnimation:animation forKey:nil]; + if (completion) - { - [animation setCompletionBlock:^(POPAnimation *animation, BOOL finished) { - completion(); - }]; - } + { + [animation setCompletionBlock:^(POPAnimation *animation, BOOL finished) { + completion(); + }]; + } } @end