From e2118eb412b40a367ad22906e8e9f6413f522e7a Mon Sep 17 00:00:00 2001 From: Alexander Filippov Date: Mon, 8 Aug 2016 12:22:19 +0300 Subject: [PATCH 01/10] Version Bump to 2.1.3 and MBProgressHUD to v1.0 --- MWPhotoBrowser.podspec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MWPhotoBrowser.podspec b/MWPhotoBrowser.podspec index 2b8d0e563..c320039f3 100644 --- a/MWPhotoBrowser.podspec +++ b/MWPhotoBrowser.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = 'MWPhotoBrowser' - s.version = '2.1.2' + s.version = '2.1.3' s.license = 'MIT' s.summary = 'A simple iOS photo and video browser with optional grid view, captions and selections.' s.description = <<-DESCRIPTION @@ -25,7 +25,7 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/mwaterfall/MWPhotoBrowser.git', - :tag => '2.1.2' + :tag => '2.1.3' } s.platform = :ios, '7.0' s.source_files = 'Pod/Classes/**/*' @@ -37,7 +37,7 @@ Pod::Spec.new do |s| s.frameworks = 'ImageIO', 'QuartzCore', 'AssetsLibrary', 'MediaPlayer' s.weak_frameworks = 'Photos' - s.dependency 'MBProgressHUD', '~> 0.9' + s.dependency 'MBProgressHUD', '~> 1.0' s.dependency 'DACircularProgress', '~> 2.3' # SDWebImage From 08369a8e37e993e331603dead7c75dc1c28b1e08 Mon Sep 17 00:00:00 2001 From: Alexander Filippov Date: Tue, 27 Mar 2018 15:52:47 +0300 Subject: [PATCH 02/10] Bump SDWebImage to 4.x branch --- MWPhotoBrowser.podspec | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/MWPhotoBrowser.podspec b/MWPhotoBrowser.podspec index c320039f3..de2817bd8 100644 --- a/MWPhotoBrowser.podspec +++ b/MWPhotoBrowser.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = 'MWPhotoBrowser' - s.version = '2.1.3' + s.version = '2.1.4' s.license = 'MIT' s.summary = 'A simple iOS photo and video browser with optional grid view, captions and selections.' s.description = <<-DESCRIPTION @@ -25,7 +25,7 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/mwaterfall/MWPhotoBrowser.git', - :tag => '2.1.3' + :branch => 'master' } s.platform = :ios, '7.0' s.source_files = 'Pod/Classes/**/*' @@ -40,9 +40,6 @@ Pod::Spec.new do |s| s.dependency 'MBProgressHUD', '~> 1.0' s.dependency 'DACircularProgress', '~> 2.3' - # SDWebImage - # 3.7.2 contains bugs downloading local files - # https://github.com/rs/SDWebImage/issues/1109 - s.dependency 'SDWebImage', '~> 3.7', '!= 3.7.2' + s.dependency 'SDWebImage', '~> 4.3' end From f35ec99ea5bd1f5b2c905ab159764f07e3571786 Mon Sep 17 00:00:00 2001 From: Alexander Filippov Date: Tue, 27 Mar 2018 16:19:07 +0300 Subject: [PATCH 03/10] Update MWPhoto for SDWebImage 4.3 --- Pod/Classes/MWPhoto.m | 47 +++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/Pod/Classes/MWPhoto.m b/Pod/Classes/MWPhoto.m index 6b1f697cc..c2ea66805 100644 --- a/Pod/Classes/MWPhoto.m +++ b/Pod/Classes/MWPhoto.m @@ -6,7 +6,6 @@ // Copyright 2010 d3i. All rights reserved. // -#import #import #import #import @@ -19,7 +18,7 @@ @interface MWPhoto () { id _webImageOperation; PHImageRequestID _assetRequestID; PHImageRequestID _assetVideoRequestID; - + } @property (nonatomic, strong) UIImage *image; @@ -38,7 +37,7 @@ @implementation MWPhoto #pragma mark - Class Methods + (MWPhoto *)photoWithImage:(UIImage *)image { - return [[MWPhoto alloc] initWithImage:image]; + return [[MWPhoto alloc] initWithImage:image]; } + (MWPhoto *)photoWithURL:(NSURL *)url { @@ -212,27 +211,27 @@ - (void)performLoadUnderlyingImageAndNotify { - (void)_performLoadUnderlyingImageAndNotifyWithWebURL:(NSURL *)url { @try { SDWebImageManager *manager = [SDWebImageManager sharedManager]; - _webImageOperation = [manager downloadImageWithURL:url - options:0 - progress:^(NSInteger receivedSize, NSInteger expectedSize) { - if (expectedSize > 0) { - float progress = receivedSize / (float)expectedSize; - NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithFloat:progress], @"progress", - self, @"photo", nil]; - [[NSNotificationCenter defaultCenter] postNotificationName:MWPHOTO_PROGRESS_NOTIFICATION object:dict]; - } + _webImageOperation = [manager loadImageWithURL:url + options:0 + progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL *imageURL) { + if (expectedSize > 0) { + float progress = receivedSize / (float)expectedSize; + NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithFloat:progress], @"progress", + self, @"photo", nil]; + [[NSNotificationCenter defaultCenter] postNotificationName:MWPHOTO_PROGRESS_NOTIFICATION object:dict]; } - completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { - if (error) { - MWLog(@"SDWebImage failed to download image: %@", error); - } - _webImageOperation = nil; - self.underlyingImage = image; - dispatch_async(dispatch_get_main_queue(), ^{ - [self imageLoadingComplete]; - }); - }]; + } + completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + if (error) { + MWLog(@"SDWebImage failed to download image: %@", error); + } + _webImageOperation = nil; + self.underlyingImage = image; + dispatch_async(dispatch_get_main_queue(), ^{ + [self imageLoadingComplete]; + }); + }]; } @catch (NSException *e) { MWLog(@"Photo from web: %@", e); _webImageOperation = nil; @@ -313,7 +312,7 @@ - (void)_performLoadUnderlyingImageAndNotifyWithAsset:(PHAsset *)asset targetSiz // Release if we can get it again from path or url - (void)unloadUnderlyingImage { _loadingInProgress = NO; - self.underlyingImage = nil; + self.underlyingImage = nil; } - (void)imageLoadingComplete { From af9888f230836101de451931839369620441b18c Mon Sep 17 00:00:00 2001 From: Alexander Filippov Date: Tue, 14 Jan 2020 16:20:01 +0300 Subject: [PATCH 04/10] MBProgressHUD update --- Pod/Classes/MWPhotoBrowser.m | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Pod/Classes/MWPhotoBrowser.m b/Pod/Classes/MWPhotoBrowser.m index 0de7faaab..241e44f6b 100644 --- a/Pod/Classes/MWPhotoBrowser.m +++ b/Pod/Classes/MWPhotoBrowser.m @@ -1643,25 +1643,25 @@ - (MBProgressHUD *)progressHUD { } - (void)showProgressHUDWithMessage:(NSString *)message { - self.progressHUD.labelText = message; + self.progressHUD.label.text = message; self.progressHUD.mode = MBProgressHUDModeIndeterminate; - [self.progressHUD show:YES]; + [self.progressHUD showAnimated:YES]; self.navigationController.navigationBar.userInteractionEnabled = NO; } - (void)hideProgressHUD:(BOOL)animated { - [self.progressHUD hide:animated]; + [self.progressHUD hideAnimated:animated]; self.navigationController.navigationBar.userInteractionEnabled = YES; } - (void)showProgressHUDCompleteMessage:(NSString *)message { if (message) { - if (self.progressHUD.isHidden) [self.progressHUD show:YES]; - self.progressHUD.labelText = message; + if (self.progressHUD.isHidden) [self.progressHUD showAnimated:YES]; + self.progressHUD.label.text = message; self.progressHUD.mode = MBProgressHUDModeCustomView; - [self.progressHUD hide:YES afterDelay:1.5]; + [self.progressHUD hideAnimated:YES afterDelay:1.5]; } else { - [self.progressHUD hide:YES]; + [self.progressHUD hideAnimated:YES]; } self.navigationController.navigationBar.userInteractionEnabled = YES; } From dcea6a1006e0e96bb463950462af54a9d603f926 Mon Sep 17 00:00:00 2001 From: Alexander Filippov Date: Tue, 19 Oct 2021 15:27:55 +0300 Subject: [PATCH 05/10] NavigationBar tint color --- Pod/Classes/MWPhotoBrowser.h | 1 + Pod/Classes/MWPhotoBrowser.m | 279 ++++++++++++++++++----------------- 2 files changed, 142 insertions(+), 138 deletions(-) diff --git a/Pod/Classes/MWPhotoBrowser.h b/Pod/Classes/MWPhotoBrowser.h index 4225f9cc1..a47390008 100644 --- a/Pod/Classes/MWPhotoBrowser.h +++ b/Pod/Classes/MWPhotoBrowser.h @@ -40,6 +40,7 @@ @interface MWPhotoBrowser : UIViewController +@property (nonatomic) UIColor *navigationBarTintColor; @property (nonatomic, weak) IBOutlet id delegate; @property (nonatomic) BOOL zoomPhotosToFill; @property (nonatomic) BOOL displayNavArrows; diff --git a/Pod/Classes/MWPhotoBrowser.m b/Pod/Classes/MWPhotoBrowser.m index 241e44f6b..3a8b26606 100644 --- a/Pod/Classes/MWPhotoBrowser.m +++ b/Pod/Classes/MWPhotoBrowser.m @@ -50,7 +50,7 @@ - (id)initWithCoder:(NSCoder *)decoder { } - (void)_initialisation { - + // Defaults NSNumber *isVCBasedStatusBarAppearanceNum = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIViewControllerBasedStatusBarAppearance"]; if (isVCBasedStatusBarAppearanceNum) { @@ -82,13 +82,13 @@ - (void)_initialisation { _currentGridContentOffset = CGPointMake(0, CGFLOAT_MAX); _didSavePreviousStateOfNavBar = NO; self.automaticallyAdjustsScrollViewInsets = NO; - + // Listen for MWPhoto notifications [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleMWPhotoLoadingDidEndNotification:) name:MWPHOTO_LOADING_DID_END_NOTIFICATION object:nil]; - + } - (void)dealloc { @@ -125,28 +125,31 @@ - (void)didReceiveMemoryWarning { // Release any cached data, images, etc that aren't in use. [self releaseAllUnderlyingPhotos:YES]; [_recycledPages removeAllObjects]; - + // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; - + } #pragma mark - View Loading // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. - (void)viewDidLoad { - + // Validate grid settings if (_startOnGrid) _enableGrid = YES; if (_enableGrid) { _enableGrid = [_delegate respondsToSelector:@selector(photoBrowser:thumbPhotoAtIndex:)]; } if (!_enableGrid) _startOnGrid = NO; - + // View self.view.backgroundColor = [UIColor blackColor]; self.view.clipsToBounds = YES; - + if (_navigationBarTintColor) { + self.navigationController.navigationBar.tintColor = _navigationBarTintColor; + } + // Setup paging scrolling view CGRect pagingScrollViewFrame = [self frameForPagingScrollView]; _pagingScrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame]; @@ -158,7 +161,7 @@ - (void)viewDidLoad { _pagingScrollView.backgroundColor = [UIColor blackColor]; _pagingScrollView.contentSize = [self contentSizeForPagingScrollView]; [self.view addSubview:_pagingScrollView]; - + // Toolbar _toolbar = [[UIToolbar alloc] initWithFrame:[self frameForToolbarAtOrientation:self.interfaceOrientation]]; _toolbar.tintColor = [UIColor whiteColor]; @@ -167,7 +170,7 @@ - (void)viewDidLoad { [_toolbar setBackgroundImage:nil forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsLandscapePhone]; _toolbar.barStyle = UIBarStyleBlackTranslucent; _toolbar.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth; - + // Toolbar Items if (self.displayNavArrows) { NSString *arrowPathFormat = @"MWPhotoBrowser.bundle/UIBarButtonItemArrow%@"; @@ -179,32 +182,32 @@ - (void)viewDidLoad { if (self.displayActionButton) { _actionButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(actionButtonPressed:)]; } - + // Update [self reloadData]; - + // Swipe to dismiss if (_enableSwipeToDismiss) { UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(doneButtonPressed:)]; swipeGesture.direction = UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionUp; [self.view addGestureRecognizer:swipeGesture]; } - + // Super [super viewDidLoad]; - + } - (void)performLayout { - + // Setup _performingLayout = YES; NSUInteger numberOfPhotos = [self numberOfPhotos]; - + // Setup pages [_visiblePages removeAllObjects]; [_recycledPages removeAllObjects]; - + // Navigation buttons if ([self.navigationController.viewControllers objectAtIndex:0] == self) { // We're first on stack so show done button @@ -284,15 +287,15 @@ - (void)performLayout { } else { [self.view addSubview:_toolbar]; } - + // Update nav [self updateNavigation]; - + // Content offset _pagingScrollView.contentOffset = [self contentOffsetForPageAtIndex:_currentPageIndex]; [self tilePages]; _performingLayout = NO; - + } // Release any retained subviews of the main view. @@ -330,10 +333,10 @@ - (BOOL)presentingViewControllerPrefersStatusBarHidden { #pragma mark - Appearance - (void)viewWillAppear:(BOOL)animated { - + // Super [super viewWillAppear:animated]; - + // Status bar if (!_viewHasAppearedInitially) { _leaveStatusBarAlone = [self presentingViewControllerPrefersStatusBarHidden]; @@ -347,29 +350,29 @@ - (void)viewWillAppear:(BOOL)animated { _previousStatusBarStyle = [[UIApplication sharedApplication] statusBarStyle]; [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:animated]; } - + // Navigation bar appearance if (!_viewIsActive && [self.navigationController.viewControllers objectAtIndex:0] != self) { [self storePreviousNavBarAppearance]; } [self setNavBarAppearance:animated]; - + // Update UI [self hideControlsAfterDelay]; - + // Initial appearance if (!_viewHasAppearedInitially) { if (_startOnGrid) { [self showGrid:NO]; } } - + // If rotation occured while we're presenting a modal // and the index changed, make sure we show the right one now if (_currentPageIndex != _pageIndexBeforeRotation) { [self jumpToPageAtIndex:_pageIndexBeforeRotation animated:NO]; } - + // Layout [self.view setNeedsLayout]; @@ -378,7 +381,7 @@ - (void)viewWillAppear:(BOOL)animated { - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; _viewIsActive = YES; - + // Autoplay if first is video if (!_viewHasAppearedInitially) { if (_autoPlayOnAppear) { @@ -388,16 +391,16 @@ - (void)viewDidAppear:(BOOL)animated { } } } - + _viewHasAppearedInitially = YES; - + } - (void)viewWillDisappear:(BOOL)animated { - + // Detect if rotation occurs while we're presenting a modal _pageIndexBeforeRotation = _currentPageIndex; - + // Check that we're disappearing for good // self.isMovingFromParentViewController just doesn't work, ever. Or self.isBeingDismissed if ((_doneButton && self.navigationController.isBeingDismissed) || @@ -406,25 +409,25 @@ - (void)viewWillDisappear:(BOOL)animated { // State _viewIsActive = NO; [self clearCurrentVideo]; // Clear current playing video - + // Bar state / appearance [self restorePreviousNavBarAppearance:animated]; - + } - + // Controls [self.navigationController.navigationBar.layer removeAllAnimations]; // Stop all animations on nav bar [NSObject cancelPreviousPerformRequestsWithTarget:self]; // Cancel any pending toggles from taps [self setControlsHidden:NO animated:NO permanent:YES]; - + // Status bar if (!_leaveStatusBarAlone && UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) { [[UIApplication sharedApplication] setStatusBarStyle:_previousStatusBarStyle animated:animated]; } - + // Super [super viewWillDisappear:animated]; - + } - (void)willMoveToParentViewController:(UIViewController *)parent { @@ -489,28 +492,28 @@ - (void)viewWillLayoutSubviews { } - (void)layoutVisiblePages { - + // Flag _performingLayout = YES; - + // Toolbar _toolbar.frame = [self frameForToolbarAtOrientation:self.interfaceOrientation]; - + // Remember index NSUInteger indexPriorToLayout = _currentPageIndex; - + // Get paging scroll view frame to determine if anything needs changing CGRect pagingScrollViewFrame = [self frameForPagingScrollView]; - + // Frame needs changing if (!_skipNextPagingScrollViewPositioning) { _pagingScrollView.frame = pagingScrollViewFrame; } _skipNextPagingScrollViewPositioning = NO; - + // Recalculate contentSize based on current orientation _pagingScrollView.contentSize = [self contentSizeForPagingScrollView]; - + // Adjust frames and configuration of each visible page for (MWZoomingScrollView *page in _visiblePages) { NSUInteger index = page.index; @@ -524,7 +527,7 @@ - (void)layoutVisiblePages { if (page.playButton) { page.playButton.frame = [self frameForPlayButton:page.playButton atIndex:index]; } - + // Adjust scales if bounds has changed since last time if (!CGRectEqualToRect(_previousLayoutBounds, self.view.bounds)) { // Update zooms for new bounds @@ -533,18 +536,18 @@ - (void)layoutVisiblePages { } } - + // Adjust video loading indicator if it's visible [self positionVideoLoadingIndicator]; - + // 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; - + } #pragma mark - Rotation @@ -558,30 +561,30 @@ - (UIInterfaceOrientationMask)supportedInterfaceOrientations { } - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { - + // Remember page index before rotation _pageIndexBeforeRotation = _currentPageIndex; _rotating = YES; - + // In iOS 7 the nav bar gets shown after rotation, but might as well do this for everything! if ([self areControlsHidden]) { // Force hidden self.navigationController.navigationBarHidden = YES; } - + } - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { - + // Perform layout _currentPageIndex = _pageIndexBeforeRotation; - + // Delay control holding [self hideControlsAfterDelay]; - + // Layout [self layoutVisiblePages]; - + } - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { @@ -600,10 +603,10 @@ - (NSUInteger)currentIndex { } - (void)reloadData { - + // Reset _photoCount = NSNotFound; - + // Get data NSUInteger numberOfPhotos = [self numberOfPhotos]; [self releaseAllUnderlyingPhotos:YES]; @@ -620,7 +623,7 @@ - (void)reloadData { } else { _currentPageIndex = 0; } - + // Update layout if ([self isViewLoaded]) { while (_pagingScrollView.subviews.count) { @@ -629,7 +632,7 @@ - (void)reloadData { [self performLayout]; [self.view setNeedsLayout]; } - + } - (NSUInteger)numberOfPhotos { @@ -757,7 +760,7 @@ - (void)handleMWPhotoLoadingDidEndNotification:(NSNotification *)notification { [page displayImage]; [self loadAdjacentPhotosIfNecessary:photo]; } else { - + // Failed to load [page displayImageFailure]; } @@ -769,7 +772,7 @@ - (void)handleMWPhotoLoadingDidEndNotification:(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 @@ -780,7 +783,7 @@ - (void)tilePages { 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 NSInteger pageIndex; for (MWZoomingScrollView *page in _visiblePages) { @@ -798,11 +801,11 @@ - (void)tilePages { [_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 new page MWZoomingScrollView *page = [self dequeueRecycledPage]; if (!page) { @@ -813,7 +816,7 @@ - (void)tilePages { [_pagingScrollView addSubview:page]; MWLog(@"Added page at index %lu", (unsigned long)index); - + // Add caption MWCaptionView *captionView = [self captionViewForPhotoAtIndex:index]; if (captionView) { @@ -821,7 +824,7 @@ - (void)tilePages { [_pagingScrollView addSubview:captionView]; page.captionView = captionView; } - + // Add play button if needed if (page.displayingVideo) { UIButton *playButton = [UIButton buttonWithType:UIButtonTypeCustom]; @@ -833,7 +836,7 @@ - (void)tilePages { [_pagingScrollView addSubview:playButton]; page.playButton = playButton; } - + // Add selected button if (self.displaySelectionButtons) { UIButton *selectedButton = [UIButton buttonWithType:UIButtonTypeCustom]; @@ -853,19 +856,19 @@ - (void)tilePages { page.selectedButton = selectedButton; selectedButton.selected = [self photoIsSelectedAtIndex:index]; } - + } } - + } - (void)updateVisiblePageStates { NSSet *copy = [_visiblePages copy]; for (MWZoomingScrollView *page in copy) { - + // Update selection page.selectedButton.selected = [self photoIsSelectedAtIndex:page.index]; - + } } @@ -911,24 +914,24 @@ - (MWZoomingScrollView *)dequeueRecycledPage { // Handle page changes - (void)didStartViewingPageAtIndex:(NSUInteger)index { - + // Handle 0 photos if (![self numberOfPhotos]) { // Show controls [self setControlsHidden:NO animated:YES permanent:YES]; return; } - + // Handle video on page change if (!_rotating && index != _currentVideoIndex) { [self clearCurrentVideo]; } - + // Release images further away than +/-1 NSUInteger i; if (index > 0) { // Release anything < index - 1 - for (i = 0; i < index-1; i++) { + for (i = 0; i < index-1; i++) { id photo = [_photos objectAtIndex:i]; if (photo != [NSNull null]) { [photo unloadUnderlyingImage]; @@ -948,7 +951,7 @@ - (void)didStartViewingPageAtIndex:(NSUInteger)index { } } } - + // Load adjacent images if needed and the photo is already // loaded. Also called after photo has been loaded in background id currentPhoto = [self photoAtIndex:index]; @@ -956,17 +959,17 @@ - (void)didStartViewingPageAtIndex:(NSUInteger)index { // photo loaded so load ajacent now [self loadAdjacentPhotosIfNecessary:currentPhoto]; } - + // Notify delegate if (index != _previousPageIndex) { if ([_delegate respondsToSelector:@selector(photoBrowser:didDisplayPhotoAtIndex:)]) [_delegate photoBrowser:self didDisplayPhotoAtIndex:index]; _previousPageIndex = index; } - + // Update nav [self updateNavigation]; - + } #pragma mark - Frame Calculations @@ -1045,13 +1048,13 @@ - (CGRect)frameForPlayButton:(UIButton *)playButton atIndex:(NSUInteger)index { #pragma mark - UIScrollView Delegate - (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))); @@ -1062,7 +1065,7 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView { if (_currentPageIndex != previousCurrentPage) { [self didStartViewingPageAtIndex:index]; } - + } - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { @@ -1078,7 +1081,7 @@ - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { #pragma mark - Navigation - (void)updateNavigation { - + // Title NSUInteger numberOfPhotos = [self numberOfPhotos]; if (_gridController) { @@ -1102,11 +1105,11 @@ - (void)updateNavigation { } else { self.title = nil; } - + // Buttons _previousButton.enabled = (_currentPageIndex > 0); _nextButton.enabled = (_currentPageIndex < numberOfPhotos - 1); - + // Disable action button if there is no image or it's a video MWPhoto *photo = [self photoAtIndex:_currentPageIndex]; if ([photo underlyingImage] == nil || ([photo respondsToSelector:@selector(isVideo)] && photo.isVideo)) { @@ -1116,21 +1119,21 @@ - (void)updateNavigation { _actionButton.enabled = YES; _actionButton.tintColor = nil; } - + } - (void)jumpToPageAtIndex:(NSUInteger)index animated:(BOOL)animated { - + // Change page if (index < [self numberOfPhotos]) { CGRect pageFrame = [self frameForPageAtIndex:index]; [_pagingScrollView setContentOffset:CGPointMake(pageFrame.origin.x - PADDING, 0) animated:animated]; [self updateNavigation]; } - + // Update timer to give more time [self hideControlsAfterDelay]; - + } - (void)gotoPreviousPage { @@ -1194,7 +1197,7 @@ - (NSUInteger)indexForPlayButton:(UIView *)playButton { - (void)playVideoAtIndex:(NSUInteger)index { id photo = [self photoAtIndex:index]; if ([photo respondsToSelector:@selector(getVideoURL:)]) { - + // Valid for playing [self clearCurrentVideo]; _currentVideoIndex = index; @@ -1217,7 +1220,7 @@ - (void)playVideoAtIndex:(NSUInteger)index { } }); }]; - + } } @@ -1229,7 +1232,7 @@ - (void)_playVideo:(NSURL *)videoURL atPhotoIndex:(NSUInteger)index { _currentVideoPlayerViewController.moviePlayer.shouldAutoplay = YES; _currentVideoPlayerViewController.moviePlayer.scalingMode = MPMovieScalingModeAspectFit; _currentVideoPlayerViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; - + // Remove the movie player view controller from the "playback did finish" notification observers // Observe ourselves so we can get it to use the crossfade transition [[NSNotificationCenter defaultCenter] removeObserver:_currentVideoPlayerViewController @@ -1246,15 +1249,15 @@ - (void)_playVideo:(NSURL *)videoURL atPhotoIndex:(NSUInteger)index { } - (void)videoFinishedCallback:(NSNotification*)notification { - + // Remove observer [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:_currentVideoPlayerViewController.moviePlayer]; - + // Clear up [self clearCurrentVideo]; - + // Dismiss BOOL error = [[[notification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey] intValue] == MPMovieFinishReasonPlaybackError; if (error) { @@ -1265,7 +1268,7 @@ - (void)videoFinishedCallback:(NSNotification*)notification { } else { [self dismissViewControllerAnimated:YES completion:nil]; } - + } - (void)clearCurrentVideo { @@ -1308,10 +1311,10 @@ - (void)showGridAnimated { - (void)showGrid:(BOOL)animated { if (_gridController) return; - + // Clear video [self clearCurrentVideo]; - + // Init grid controller _gridController = [[MWGridViewController alloc] init]; _gridController.initialContentOffset = _currentGridContentOffset; @@ -1322,15 +1325,15 @@ - (void)showGrid:(BOOL)animated { // Stop specific layout being triggered _skipNextPagingScrollViewPositioning = YES; - + // Add as a child view controller [self addChildViewController:_gridController]; [self.view addSubview:_gridController.view]; - + // Perform any adjustments [_gridController.view layoutIfNeeded]; [_gridController adjustOffsetsAsRequired]; - + // Hide action button on nav bar if it exists if (self.navigationItem.rightBarButtonItem == _actionButton) { _gridPreviousRightNavItem = _actionButton; @@ -1338,11 +1341,11 @@ - (void)showGrid:(BOOL)animated { } else { _gridPreviousRightNavItem = nil; } - + // Update [self updateNavigation]; [self setControlsHidden:NO animated:YES permanent:YES]; - + // Animate grid in and photo scroller out [_gridController willMoveToParentViewController:self]; [UIView animateWithDuration:animated ? 0.3 : 0 animations:^(void) { @@ -1353,34 +1356,34 @@ - (void)showGrid:(BOOL)animated { } completion:^(BOOL finished) { [_gridController didMoveToParentViewController:self]; }]; - + } - (void)hideGrid { - + if (!_gridController) return; - + // Remember previous content offset _currentGridContentOffset = _gridController.collectionView.contentOffset; - + // Restore action button if it was removed if (_gridPreviousRightNavItem == _actionButton && _actionButton) { [self.navigationItem setRightBarButtonItem:_gridPreviousRightNavItem animated:YES]; } - + // Position prior to hide animation CGRect newPagingFrame = [self frameForPagingScrollView]; newPagingFrame = CGRectOffset(newPagingFrame, 0, (self.startOnGrid ? 1 : -1) * newPagingFrame.size.height); _pagingScrollView.frame = newPagingFrame; - + // Remember and remove controller now so things can detect a nil grid controller MWGridViewController *tmpGridController = _gridController; _gridController = nil; - + // Update [self updateNavigation]; [self updateVisiblePageStates]; - + // Animate, hide grid and show paging scroll view [UIView animateWithDuration:0.3 animations:^{ tmpGridController.view.frame = CGRectOffset(self.view.bounds, 0, (self.startOnGrid ? -1 : 1) * self.view.bounds.size.height); @@ -1399,46 +1402,46 @@ - (void)hideGrid { // If permanent then we don't set timers to hide again // Fades all controls on iOS 5 & 6, and iOS 7 controls slide and fade - (void)setControlsHidden:(BOOL)hidden animated:(BOOL)animated permanent:(BOOL)permanent { - + // Force visible if (![self numberOfPhotos] || _gridController || _alwaysShowControls) hidden = NO; - + // Cancel any timers [self cancelControlHiding]; - + // Animations & positions CGFloat animatonOffset = 20; CGFloat animationDuration = (animated ? 0.35 : 0); - + // Status bar if (!_leaveStatusBarAlone) { // Hide status bar if (!_isVCBasedStatusBarAppearance) { - + // Non-view controller based [[UIApplication sharedApplication] setStatusBarHidden:hidden withAnimation:animated ? UIStatusBarAnimationSlide : UIStatusBarAnimationNone]; - + } else { - + // View controller based so animate away _statusBarShouldBeHidden = hidden; [UIView animateWithDuration:animationDuration animations:^(void) { [self setNeedsStatusBarAppearanceUpdate]; } completion:^(BOOL finished) {}]; - + } } - + // Toolbar, nav bar and captions // Pre-appear animation positions for sliding if ([self areControlsHidden] && !hidden && animated) { - + // Toolbar _toolbar.frame = CGRectOffset([self frameForToolbarAtOrientation:self.interfaceOrientation], 0, animatonOffset); - + // Captions for (MWZoomingScrollView *page in _visiblePages) { if (page.captionView) { @@ -1449,15 +1452,15 @@ - (void)setControlsHidden:(BOOL)hidden animated:(BOOL)animated permanent:(BOOL)p v.frame = CGRectOffset(captionFrame, 0, animatonOffset); } } - + } [UIView animateWithDuration:animationDuration animations:^(void) { - + CGFloat alpha = hidden ? 0 : 1; // Nav bar slides up on it's own on iOS 7+ [self.navigationController.navigationBar setAlpha:alpha]; - + // Toolbar _toolbar.frame = [self frameForToolbarAtOrientation:self.interfaceOrientation]; if (hidden) _toolbar.frame = CGRectOffset(_toolbar.frame, 0, animatonOffset); @@ -1475,7 +1478,7 @@ - (void)setControlsHidden:(BOOL)hidden animated:(BOOL)animated permanent:(BOOL)p v.alpha = alpha; } } - + // Selected buttons for (MWZoomingScrollView *page in _visiblePages) { if (page.selectedButton) { @@ -1487,12 +1490,12 @@ - (void)setControlsHidden:(BOOL)hidden animated:(BOOL)animated permanent:(BOOL)p } } completion:^(BOOL finished) {}]; - + // Control hiding timer // Will cancel existing timer but only begin hiding if // they are visible if (!permanent) [self hideControlsAfterDelay]; - + } - (BOOL)prefersStatusBarHidden { @@ -1583,22 +1586,22 @@ - (void)actionButtonPressed:(id)sender { // Only react when image has loaded id photo = [self photoAtIndex:_currentPageIndex]; if ([self numberOfPhotos] > 0 && [photo underlyingImage]) { - + // If they have defined a delegate method then just message them if ([self.delegate respondsToSelector:@selector(photoBrowser:actionButtonPressedForPhotoAtIndex:)]) { - + // Let delegate handle things [self.delegate photoBrowser:self actionButtonPressedForPhotoAtIndex:_currentPageIndex]; - + } else { - + // Show activity view controller NSMutableArray *items = [NSMutableArray arrayWithObject:[photo underlyingImage]]; if (photo.caption) { [items addObject:photo.caption]; } self.activityViewController = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:nil]; - + // Show loading spinner after a couple of seconds double delayInSeconds = 2.0; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); @@ -1622,12 +1625,12 @@ - (void)actionButtonPressed:(id)sender { [self presentViewController:self.activityViewController animated:YES completion:nil]; } - + // Keep controls hidden [self setControlsHidden:NO animated:YES permanent:YES]; } - + } #pragma mark - Action Progress From f422d32c3e3bd7d80ac3756da43eb2fea1ec74d8 Mon Sep 17 00:00:00 2001 From: Alexander Filippov Date: Tue, 19 Oct 2021 15:50:57 +0300 Subject: [PATCH 06/10] Fix --- Pod/Classes/MWPhotoBrowser.m | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Pod/Classes/MWPhotoBrowser.m b/Pod/Classes/MWPhotoBrowser.m index 3a8b26606..937e44695 100644 --- a/Pod/Classes/MWPhotoBrowser.m +++ b/Pod/Classes/MWPhotoBrowser.m @@ -146,9 +146,6 @@ - (void)viewDidLoad { // View self.view.backgroundColor = [UIColor blackColor]; self.view.clipsToBounds = YES; - if (_navigationBarTintColor) { - self.navigationController.navigationBar.tintColor = _navigationBarTintColor; - } // Setup paging scrolling view CGRect pagingScrollViewFrame = [self frameForPagingScrollView]; @@ -164,7 +161,7 @@ - (void)viewDidLoad { // Toolbar _toolbar = [[UIToolbar alloc] initWithFrame:[self frameForToolbarAtOrientation:self.interfaceOrientation]]; - _toolbar.tintColor = [UIColor whiteColor]; + _toolbar.tintColor = _navigationBarTintColor ?: [UIColor whiteColor]; _toolbar.barTintColor = nil; [_toolbar setBackgroundImage:nil forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault]; [_toolbar setBackgroundImage:nil forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsLandscapePhone]; From 5061f231cc201140e6f140b7e503eac9c62d156b Mon Sep 17 00:00:00 2001 From: Alexander Filippov Date: Tue, 19 Oct 2021 16:02:01 +0300 Subject: [PATCH 07/10] Another --- Pod/Classes/MWPhotoBrowser.m | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Pod/Classes/MWPhotoBrowser.m b/Pod/Classes/MWPhotoBrowser.m index 937e44695..770c198ab 100644 --- a/Pod/Classes/MWPhotoBrowser.m +++ b/Pod/Classes/MWPhotoBrowser.m @@ -222,13 +222,21 @@ - (void)performLayout { UIViewController *previousViewController = [self.navigationController.viewControllers objectAtIndex:self.navigationController.viewControllers.count-2]; NSString *backButtonTitle = previousViewController.navigationItem.backBarButtonItem ? previousViewController.navigationItem.backBarButtonItem.title : previousViewController.title; UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle:backButtonTitle style:UIBarButtonItemStylePlain target:nil action:nil]; + NSDictionary *titleAttributes; + if (_navigationBarTintColor) { + titleAttributes = @{ + NSForegroundColorAttributeName: _navigationBarTintColor + }; + } else { + titleAttributes = @{}; + } // Appearance [newBackButton setBackButtonBackgroundImage:nil forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; [newBackButton setBackButtonBackgroundImage:nil forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone]; [newBackButton setBackButtonBackgroundImage:nil forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault]; [newBackButton setBackButtonBackgroundImage:nil forState:UIControlStateHighlighted barMetrics:UIBarMetricsLandscapePhone]; - [newBackButton setTitleTextAttributes:[NSDictionary dictionary] forState:UIControlStateNormal]; - [newBackButton setTitleTextAttributes:[NSDictionary dictionary] forState:UIControlStateHighlighted]; + [newBackButton setTitleTextAttributes:titleAttributes forState:UIControlStateNormal]; + [newBackButton setTitleTextAttributes:titleAttributes forState:UIControlStateHighlighted]; _previousViewControllerBackButton = previousViewController.navigationItem.backBarButtonItem; // remember previous previousViewController.navigationItem.backBarButtonItem = newBackButton; } From 6b6a063bf11a283f5b9e277298a53c664a31836b Mon Sep 17 00:00:00 2001 From: Alexander Filippov Date: Tue, 19 Oct 2021 17:22:01 +0300 Subject: [PATCH 08/10] Image back button tint --- Pod/Classes/MWPhotoBrowser.m | 1 + 1 file changed, 1 insertion(+) diff --git a/Pod/Classes/MWPhotoBrowser.m b/Pod/Classes/MWPhotoBrowser.m index 770c198ab..b883d0d5d 100644 --- a/Pod/Classes/MWPhotoBrowser.m +++ b/Pod/Classes/MWPhotoBrowser.m @@ -227,6 +227,7 @@ - (void)performLayout { titleAttributes = @{ NSForegroundColorAttributeName: _navigationBarTintColor }; + newBackButton.tintColor = _navigationBarTintColor; } else { titleAttributes = @{}; } From a5572eb38121c5868bbab788c7f9bba2d083455e Mon Sep 17 00:00:00 2001 From: Alexander Filippov Date: Fri, 7 Jul 2023 00:42:02 +0300 Subject: [PATCH 09/10] UIPageControl --- MWPhotoBrowser.podspec | 1 + Pod/Classes/MWPhotoBrowser.m | 24 ++++++++++++++++++++++-- Pod/Classes/MWPhotoBrowserPrivate.h | 1 + 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/MWPhotoBrowser.podspec b/MWPhotoBrowser.podspec index de2817bd8..c14a6a57e 100644 --- a/MWPhotoBrowser.podspec +++ b/MWPhotoBrowser.podspec @@ -39,6 +39,7 @@ Pod::Spec.new do |s| s.dependency 'MBProgressHUD', '~> 1.0' s.dependency 'DACircularProgress', '~> 2.3' + s.dependency 'Masonry', '~> 1.1' s.dependency 'SDWebImage', '~> 4.3' diff --git a/Pod/Classes/MWPhotoBrowser.m b/Pod/Classes/MWPhotoBrowser.m index b883d0d5d..e8e285948 100644 --- a/Pod/Classes/MWPhotoBrowser.m +++ b/Pod/Classes/MWPhotoBrowser.m @@ -12,6 +12,7 @@ #import "MWPhotoBrowserPrivate.h" #import "SDImageCache.h" #import "UIImage+MWPhotoBrowser.h" +#import "Masonry.h" #define PADDING 10 @@ -159,6 +160,13 @@ - (void)viewDidLoad { _pagingScrollView.contentSize = [self contentSizeForPagingScrollView]; [self.view addSubview:_pagingScrollView]; + _pageControl = [[UIPageControl alloc] initWithFrame:CGRectZero]; + _pageControl.hidesForSinglePage = YES; + _pageControl.currentPageIndicatorTintColor = [UIColor colorWithWhite:0.4 alpha:1]; + _pageControl.pageIndicatorTintColor = [UIColor colorWithWhite:0.4 alpha:0.6]; + [_pageControl addTarget:self action:@selector(pageSelected:) forControlEvents:UIControlEventValueChanged]; + [self.view addSubview:_pageControl]; + // Toolbar _toolbar = [[UIToolbar alloc] initWithFrame:[self frameForToolbarAtOrientation:self.interfaceOrientation]]; _toolbar.tintColor = _navigationBarTintColor ?: [UIColor whiteColor]; @@ -190,7 +198,12 @@ - (void)viewDidLoad { [self.view addGestureRecognizer:swipeGesture]; } - // Super + [_pageControl mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.and.right.equalTo(self.view); + make.bottom.equalTo(self.view).offset(-100); + }]; + + // Super [super viewDidLoad]; } @@ -301,7 +314,6 @@ - (void)performLayout { _pagingScrollView.contentOffset = [self contentOffsetForPageAtIndex:_currentPageIndex]; [self tilePages]; _performingLayout = NO; - } // Release any retained subviews of the main view. @@ -630,6 +642,9 @@ - (void)reloadData { _currentPageIndex = 0; } + _pageControl.numberOfPages = numberOfPhotos; + _pageControl.currentPage = _currentPageIndex; + // Update layout if ([self isViewLoaded]) { while (_pagingScrollView.subviews.count) { @@ -920,6 +935,7 @@ - (MWZoomingScrollView *)dequeueRecycledPage { // Handle page changes - (void)didStartViewingPageAtIndex:(NSUInteger)index { + _pageControl.currentPage = index; // Handle 0 photos if (![self numberOfPhotos]) { @@ -1675,4 +1691,8 @@ - (void)showProgressHUDCompleteMessage:(NSString *)message { self.navigationController.navigationBar.userInteractionEnabled = YES; } +- (void)pageSelected:(UIPageControl *)sender { + [self jumpToPageAtIndex:(NSUInteger) sender.currentPage animated:YES]; +} + @end diff --git a/Pod/Classes/MWPhotoBrowserPrivate.h b/Pod/Classes/MWPhotoBrowserPrivate.h index 5770d6787..0e75a6d10 100644 --- a/Pod/Classes/MWPhotoBrowserPrivate.h +++ b/Pod/Classes/MWPhotoBrowserPrivate.h @@ -23,6 +23,7 @@ // Views UIScrollView *_pagingScrollView; + UIPageControl *_pageControl; // Paging & layout NSMutableSet *_visiblePages, *_recycledPages; From eb20eff4c0d699fd964e720b58b6101f4426b1a0 Mon Sep 17 00:00:00 2001 From: Alexander Filippov Date: Fri, 7 Jul 2023 09:24:02 +0300 Subject: [PATCH 10/10] version bump --- MWPhotoBrowser.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MWPhotoBrowser.podspec b/MWPhotoBrowser.podspec index c14a6a57e..fe0f81b31 100644 --- a/MWPhotoBrowser.podspec +++ b/MWPhotoBrowser.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = 'MWPhotoBrowser' - s.version = '2.1.4' + s.version = '2.1.5' s.license = 'MIT' s.summary = 'A simple iOS photo and video browser with optional grid view, captions and selections.' s.description = <<-DESCRIPTION