From e4635c7b6187a382379bd4a94057104de223a129 Mon Sep 17 00:00:00 2001 From: Jui hsin Chen Date: Thu, 26 Apr 2018 11:41:30 +0800 Subject: [PATCH 1/3] Change pod file format --- Demo/Podfile | 15 ++++++++++----- Demo/Podfile.lock | 14 +++++++------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/Demo/Podfile b/Demo/Podfile index cb335507..d01088d9 100644 --- a/Demo/Podfile +++ b/Demo/Podfile @@ -1,12 +1,17 @@ source 'https://github.com/CocoaPods/Specs.git' -# ignoring warning from pods +platform :ios, '8.0' + +# ignore all warnings from all pods inhibit_all_warnings! -target "PhotoBrowserDemo" do +def all_pods + pod 'SDWebImage', '~>3.7.1' + pod 'DACircularProgress' + pod 'pop' +end -pod 'SDWebImage' -pod 'DACircularProgress' -pod 'pop' +target "PhotoBrowserDemo" do + all_pods end diff --git a/Demo/Podfile.lock b/Demo/Podfile.lock index 329f0774..1ad809ed 100644 --- a/Demo/Podfile.lock +++ b/Demo/Podfile.lock @@ -1,20 +1,20 @@ PODS: - DACircularProgress (2.3.1) - pop (1.0.9) - - SDWebImage (3.8.2): - - SDWebImage/Core (= 3.8.2) - - SDWebImage/Core (3.8.2) + - SDWebImage (3.7.6): + - SDWebImage/Core (= 3.7.6) + - SDWebImage/Core (3.7.6) DEPENDENCIES: - DACircularProgress - pop - - SDWebImage + - SDWebImage (~> 3.7.1) SPEC CHECKSUMS: DACircularProgress: 4dd437c0fc3da5161cb289e07ac449493d41db71 pop: f667631a5108a2e60d9e8797c9b32ddaf2080bce - SDWebImage: 098e97e6176540799c27e804c96653ee0833d13c + SDWebImage: c325cf02c30337336b95beff20a13df489ec0ec9 -PODFILE CHECKSUM: 7c9b8bb160246eb04b56feab0ec4a8fb149d5fa3 +PODFILE CHECKSUM: b7a7dde22263842dee0946aa36312edfaf9acf0c -COCOAPODS: 1.0.1 +COCOAPODS: 1.4.0 From d808f1dd3b429d19f0c18a2203e50e98319ead42 Mon Sep 17 00:00:00 2001 From: Jui hsin Chen Date: Thu, 26 Apr 2018 11:43:09 +0800 Subject: [PATCH 2/3] Add IDMUtils files --- Classes/IDMUtils.h | 12 +++++ Classes/IDMUtils.m | 52 +++++++++++++++++++ .../project.pbxproj | 11 +++- 3 files changed, 74 insertions(+), 1 deletion(-) create mode 100755 Classes/IDMUtils.h create mode 100755 Classes/IDMUtils.m diff --git a/Classes/IDMUtils.h b/Classes/IDMUtils.h new file mode 100755 index 00000000..933bad40 --- /dev/null +++ b/Classes/IDMUtils.h @@ -0,0 +1,12 @@ +// +// IDMUtils.h +// PhotoBrowserDemo +// +// Created by Oliver ONeill on 2/12/17. +// + +#import + +@interface IDMUtils : NSObject ++ (CGRect)adjustRect:(CGRect)rect forSafeAreaInsets:(UIEdgeInsets)insets forBounds:(CGRect)bounds adjustForStatusBar:(BOOL)adjust statusBarHeight:(int)statusBarHeight; +@end diff --git a/Classes/IDMUtils.m b/Classes/IDMUtils.m new file mode 100755 index 00000000..10eea0a3 --- /dev/null +++ b/Classes/IDMUtils.m @@ -0,0 +1,52 @@ +// +// IDMUtils.m +// PhotoBrowserDemo +// +// Created by Oliver ONeill on 2/12/17. +// + +#import "IDMUtils.h" + +@implementation IDMUtils +/** + * Adjust a rect to be moved into a safe area specified by `insets`. + * + * NOTE: this does not cover all cases. Given a rect it will reposition it if it + * falls into an unsafe area according to `insets` and `bounds`. When + * `adjustForStatusBar` is true, the rect y position will be based from the edge + * of the safe area, otherwise it will be based from zero. This allows views to + * sit behind the status bar. Status bar height is also used + * to keep positioning consistent when toggling the status bar on and off + */ ++ (CGRect)adjustRect:(CGRect)rect forSafeAreaInsets:(UIEdgeInsets)insets forBounds:(CGRect)bounds adjustForStatusBar:(BOOL)adjust statusBarHeight:(int)statusBarHeight { + BOOL isLeft = rect.origin.x <= insets.left; + // If the safe area is not specified via insets we should fall back to the + // status bar height + CGFloat insetTop = insets.top > 0 ? insets.top : statusBarHeight; + // Don't adjust for y positioning when adjustForStatusBar is false + BOOL isAtTop = (rect.origin.y <= insetTop); + BOOL isRight = rect.origin.x + rect.size.width >= bounds.size.width - insets.right; + BOOL isAtBottom = rect.origin.y + rect.size.height >= bounds.size.height - insets.bottom; + if ((isLeft) && (isRight)) { + rect.origin.x += insets.left; + rect.size.width -= insets.right + insets.left; + } else if (isLeft) { + rect.origin.x += insets.left; + } else if (isRight) { + rect.origin.x -= insets.right; + } + // if we're adjusting for status bar then we should move the view out of + // the inset + if ((adjust) && (isAtTop) && (isAtBottom)) { + rect.origin.y += insetTop; + rect.size.height -= insets.bottom + insetTop; + } else if ((adjust) && (isAtTop)) { + rect.origin.y += insetTop; + } else if ((isAtTop) && (isAtBottom)) { + rect.size.height -= insets.bottom; + } else if (isAtBottom) { + rect.origin.y -= insets.bottom; + } + return rect; +} +@end diff --git a/Demo/PhotoBrowserDemo.xcodeproj/project.pbxproj b/Demo/PhotoBrowserDemo.xcodeproj/project.pbxproj index a65a09a9..e8abd3e7 100644 --- a/Demo/PhotoBrowserDemo.xcodeproj/project.pbxproj +++ b/Demo/PhotoBrowserDemo.xcodeproj/project.pbxproj @@ -54,6 +54,7 @@ D1A1935D1758F42A00CE615F /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D1A1935C1758F42A00CE615F /* MobileCoreServices.framework */; }; D1B43D551721876000D8B807 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D1B43D541721875F00D8B807 /* QuartzCore.framework */; }; D1FA3A911805C340000FFE18 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D1FA3A901805C340000FFE18 /* Security.framework */; }; + F9DBD6BF2091820A005A6550 /* IDMUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = F9DBD6BE2091820A005A6550 /* IDMUtils.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -120,6 +121,8 @@ D1B43D541721875F00D8B807 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; D1FA3A901805C340000FFE18 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; DEF1811E2E5676DB0ECAA3AE /* Pods-PhotoBrowserDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PhotoBrowserDemo.release.xcconfig"; path = "Pods/Target Support Files/Pods-PhotoBrowserDemo/Pods-PhotoBrowserDemo.release.xcconfig"; sourceTree = ""; }; + F9DBD6BD2091820A005A6550 /* IDMUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDMUtils.h; sourceTree = ""; }; + F9DBD6BE2091820A005A6550 /* IDMUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IDMUtils.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -257,6 +260,8 @@ D1574931178DB94900B0211A /* Classes */ = { isa = PBXGroup; children = ( + F9DBD6BD2091820A005A6550 /* IDMUtils.h */, + F9DBD6BE2091820A005A6550 /* IDMUtils.m */, D157494E178DB94900B0211A /* IDMCaptionView.h */, D157494F178DB94900B0211A /* IDMCaptionView.m */, 18B74F411F4FC5B4003486F4 /* IDMMealStatusView.h */, @@ -404,13 +409,16 @@ files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-PhotoBrowserDemo-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; F88445D630091F1AA9A2F89A /* [CP] Copy Pods Resources */ = { @@ -445,6 +453,7 @@ D157496C178DB94900B0211A /* IDMTapDetectingImageView.m in Sources */, D157496D178DB94900B0211A /* IDMTapDetectingView.m in Sources */, D157496E178DB94900B0211A /* IDMZoomingScrollView.m in Sources */, + F9DBD6BF2091820A005A6550 /* IDMUtils.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; From 2487ccadafaf253f9c82feb2c06e33fcd03537f5 Mon Sep 17 00:00:00 2001 From: Jui hsin Chen Date: Thu, 26 Apr 2018 11:44:01 +0800 Subject: [PATCH 3/3] Add safe area for iphoneX --- Classes/IDMPhotoBrowser.m | 71 +++++++++++++++++++++++++++++++++------ 1 file changed, 60 insertions(+), 11 deletions(-) diff --git a/Classes/IDMPhotoBrowser.m b/Classes/IDMPhotoBrowser.m index 2b5daaaf..c704dc8c 100644 --- a/Classes/IDMPhotoBrowser.m +++ b/Classes/IDMPhotoBrowser.m @@ -10,6 +10,7 @@ #import "IDMPhotoBrowser.h" #import "IDMZoomingScrollView.h" #import "IDMMealStatusView.h" +#import "IDMUtils.h" #import "pop/POP.h" @@ -76,6 +77,7 @@ @interface IDMPhotoBrowser () { BOOL _viewIsActive; // active as in it's in the view heirarchy BOOL _autoHide; NSInteger _initalPageIndex; + CGFloat _statusBarHeight; BOOL _isdraggingPhoto; @@ -202,6 +204,8 @@ - (id)init { _scaleImage = nil; _isdraggingPhoto = NO; + + _statusBarHeight = 20.f; if ([self respondsToSelector:@selector(automaticallyAdjustsScrollViewInsets)]) self.automaticallyAdjustsScrollViewInsets = NO; @@ -500,8 +504,19 @@ - (CGRect)animationFrameForImage:(UIImage *)image presenting:(BOOL)presenting sc CGSize imageSize = image.size; - CGFloat maxWidth = CGRectGetWidth(_applicationWindow.bounds); - CGFloat maxHeight = CGRectGetHeight(_applicationWindow.bounds); + CGRect bounds = _applicationWindow.bounds; + // adjust bounds as the photo browser does + if (@available(iOS 11.0, *)) { + // use the windows safe area inset + UIWindow *window = [UIApplication sharedApplication].keyWindow; + UIEdgeInsets insets = UIEdgeInsetsMake(_statusBarHeight, 0, 0, 0); + if (window != NULL) { + insets = window.safeAreaInsets; + } + bounds = [self adjustForSafeArea:bounds adjustForStatusBar:NO forInsets:insets]; + } + CGFloat maxWidth = CGRectGetWidth(bounds); + CGFloat maxHeight = CGRectGetHeight(bounds); CGRect animationFrame = CGRectZero; @@ -636,7 +651,6 @@ - (void)viewDidLoad { [_doneButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentRight]; } else { - [_doneButton setImageEdgeInsets:UIEdgeInsetsMake(26.0f, 0.0f, 0.0f, 18.0f)]; [_doneButton setImage:_doneButtonImage forState:UIControlStateNormal]; _doneButton.imageView.contentMode = UIViewContentModeScaleAspectFit; } @@ -795,6 +809,8 @@ - (void)viewWillLayoutSubviews { // Done button _doneButton.frame = [self frameForDoneButtonAtOrientation:currentOrientation]; + // Report button + _reportButton.frame = [self frameForReportButton]; // Remember index NSUInteger indexPriorToLayout = _currentPageIndex; @@ -1194,6 +1210,7 @@ - (CGRect)frameForPagingScrollView { CGRect frame = self.view.bounds; frame.origin.x -= PADDING; frame.size.width += (2 * PADDING); + frame = [self adjustForSafeArea:frame adjustForStatusBar:false]; return frame; } @@ -1234,38 +1251,70 @@ - (CGRect)frameForToolbarAtOrientation:(UIInterfaceOrientation)orientation { if ([self isLandscape:orientation]) height = 32; - return CGRectMake(0, self.view.bounds.size.height - height, self.view.bounds.size.width, height); + CGRect rtn = CGRectMake(0, self.view.bounds.size.height - height, self.view.bounds.size.width, height); + rtn = [self adjustForSafeArea:rtn adjustForStatusBar:true]; + return rtn; } - (CGRect)frameForDoneButtonAtOrientation:(UIInterfaceOrientation)orientation { CGRect screenBound = self.view.bounds; CGFloat screenWidth = screenBound.size.width; - // if ([self isLandscape:orientation]) screenWidth = screenBound.size.height; - + if ([self isLandscape:orientation]) screenWidth = screenBound.size.height; + if(_doneButtonImage) { - return CGRectMake(screenWidth - 50, 0, 50, 58); + if (@available (iOS 11, *)) { + return CGRectMake(screenWidth - 50, self.view.safeAreaInsets.top + 7, 32, 32); + } else { + return CGRectMake(screenWidth - 50, 27, 32, 32); + } } else { - return CGRectMake(screenWidth - 65, 30, 55, 24); + if (@available (iOS 11, *)) { + return CGRectMake(screenWidth - 65, self.view.safeAreaInsets.top + 7, 55, 24); + } else { + return CGRectMake(screenWidth - 65, 27, 55, 24); + } } } - (CGRect)frameForReportButton { CGFloat height = 44; CGFloat borderWidth = 0.5; + CGRect rect = CGRectMake(-borderWidth, self.view.bounds.size.height - height, self.view.bounds.size.width + borderWidth * 2, height + borderWidth); + + if (@available(iOS 11.0, *)) { + rect = CGRectMake(-borderWidth, self.view.bounds.size.height - self.view.safeAreaInsets.bottom - height, self.view.bounds.size.width + borderWidth * 2, height + borderWidth); + } - return CGRectMake(-borderWidth, self.view.bounds.size.height - height, self.view.bounds.size.width + borderWidth * 2, height + borderWidth); + return rect; } - (CGRect)frameForCaptionView:(IDMCaptionView *)captionView atIndex:(NSUInteger)index { CGRect pageFrame = [self frameForPageAtIndex:index]; CGSize captionSize = [captionView sizeThatFits:CGSizeMake(pageFrame.size.width, 24)]; - CGRect captionFrame = CGRectMake(pageFrame.origin.x, 30, pageFrame.size.width, captionSize.height); - + CGRect captionFrame; + + if (@available (iOS 11, *)) { + captionFrame = CGRectMake(pageFrame.origin.x, self.view.safeAreaInsets.top + 10, pageFrame.size.width, captionSize.height); + } else { + captionFrame = CGRectMake(pageFrame.origin.x, 30, pageFrame.size.width, captionSize.height); + } return captionFrame; } +- (CGRect)adjustForSafeArea:(CGRect)rect adjustForStatusBar:(BOOL)adjust { + if (@available(iOS 11.0, *)) { + return [self adjustForSafeArea:rect adjustForStatusBar:adjust forInsets:self.view.safeAreaInsets]; + } + UIEdgeInsets insets = UIEdgeInsetsMake(_statusBarHeight, 0, 0, 0); + return [self adjustForSafeArea:rect adjustForStatusBar:adjust forInsets:insets]; +} + +- (CGRect)adjustForSafeArea:(CGRect)rect adjustForStatusBar:(BOOL)adjust forInsets:(UIEdgeInsets) insets { + return [IDMUtils adjustRect:rect forSafeAreaInsets:insets forBounds:self.view.bounds adjustForStatusBar:adjust statusBarHeight:_statusBarHeight]; +} + - (CGRect)frameForMealStatusViewWithIndex:(NSUInteger)index formatter:(NSNumberFormatter *)formatter { CGRect pageFrame = [self frameForPageAtIndex:index]; CGRect mealStatusFrame;