Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions BFRImageViewController/BFRImageContainerViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,23 @@

#import <UIKit/UIKit.h>

typedef NS_ENUM(NSUInteger, BFRImageAssetType) {
BFRImageAssetTypeImage,
BFRImageAssetTypeRemoteImage,
BFRImageAssetTypeGIF,
BFRImageAssetTypeLivePhoto,
BFRImageAssetTypeUnknown
};

/*! This class holds an image to view, if you need an image viewer alloc @C BFRImageViewController instead. This class isn't meant to instanitated outside of it. */
@interface BFRImageContainerViewController : UIViewController

/*! Source of the image, which should either be @c NSURL or @c UIIimage. */
@property (strong, nonatomic, nonnull) id imgSrc;

/*! The type of asset that is being represented by the given @p imgSrc. */
@property (nonatomic, assign) BFRImageAssetType assetType;

/*! This will determine whether to change certain behaviors for 3D touch considerations based on its value. */
@property (nonatomic, getter=isBeingUsedFor3DTouch) BOOL usedFor3DTouch;

Expand All @@ -29,4 +40,7 @@
/*! If there is more than one image in the containing @c BFRImageViewController - this property is set to YES to make swiping from image to image easier. */
@property (nonatomic, getter=shouldDisableHorizontalDrag) BOOL disableHorizontalDrag;

/*! Assigning YES to this property will disable autoplay for live photos when it used with 3DTouch peek feature */
@property (nonatomic, getter=shouldDisableAutoplayForLivePhoto) BOOL disableAutoplayForLivePhoto;

@end
208 changes: 160 additions & 48 deletions BFRImageViewController/BFRImageContainerViewController.m

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions BFRImageViewController/BFRImageViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,7 @@
/*! Allows you to assign an index which to show first when opening multiple images. */
@property (nonatomic, assign) NSInteger startingIndex;

/*! Allows you to enable autoplay for peek&play feature on photo live view. Default to YES */
@property (nonatomic, getter=shouldDisableAutoplayForLivePhoto) BOOL disableAutoplayForLivePhoto;

@end
3 changes: 3 additions & 0 deletions BFRImageViewController/BFRImageViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ - (instancetype)initWithImageSource:(NSArray *)images {
self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
self.enableDoneButton = YES;
self.showDoneButtonOnLeft = YES;
self.disableAutoplayForLivePhoto = YES;
self.parallaxView = [UIView new];
}

Expand All @@ -69,6 +70,7 @@ - (instancetype)initForPeekWithImageSource:(NSArray *)images {
self.enableDoneButton = YES;
self.showDoneButtonOnLeft = YES;
self.usedFor3DTouch = YES;
self.disableAutoplayForLivePhoto = YES;
self.parallaxView = [UIView new];
}

Expand Down Expand Up @@ -98,6 +100,7 @@ - (void)viewDidLoad {
imgVC.useTransparentBackground = self.isUsingTransparentBackground;
imgVC.disableSharingLongPress = self.shouldDisableSharingLongPress;
imgVC.disableHorizontalDrag = (self.images.count > 1);
imgVC.disableAutoplayForLivePhoto = self.shouldDisableAutoplayForLivePhoto;
[self.imageViewControllers addObject:imgVC];
}

Expand Down
6 changes: 6 additions & 0 deletions BFRImageViewerDemo/BFRImageViewer.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
944B4DC11BFFC0C000B9BF87 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 944B4DBF1BFFC0C000B9BF87 /* LaunchScreen.storyboard */; };
944B4DE91BFFC0E300B9BF87 /* BFRImageContainerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 944B4DE61BFFC0E300B9BF87 /* BFRImageContainerViewController.m */; };
944B4DEA1BFFC0E300B9BF87 /* BFRImageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 944B4DE81BFFC0E300B9BF87 /* BFRImageViewController.m */; };
95D4797D1F97C348001E54D4 /* FifthViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 95D4797C1F97C348001E54D4 /* FifthViewController.m */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand Down Expand Up @@ -61,6 +62,8 @@
944B4DE61BFFC0E300B9BF87 /* BFRImageContainerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BFRImageContainerViewController.m; sourceTree = "<group>"; };
944B4DE71BFFC0E300B9BF87 /* BFRImageViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BFRImageViewController.h; sourceTree = "<group>"; };
944B4DE81BFFC0E300B9BF87 /* BFRImageViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BFRImageViewController.m; sourceTree = "<group>"; };
95D4797B1F97C348001E54D4 /* FifthViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FifthViewController.h; sourceTree = "<group>"; };
95D4797C1F97C348001E54D4 /* FifthViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FifthViewController.m; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -130,6 +133,8 @@
944B4DAE1BFFC0C000B9BF87 /* Supporting Files */,
171F4AD11E96C31400F4AF01 /* FourthViewController.h */,
171F4AD21E96C31400F4AF01 /* FourthViewController.m */,
95D4797B1F97C348001E54D4 /* FifthViewController.h */,
95D4797C1F97C348001E54D4 /* FifthViewController.m */,
);
path = BFRImageViewer;
sourceTree = "<group>";
Expand Down Expand Up @@ -299,6 +304,7 @@
944B4DB91BFFC0C000B9BF87 /* SecondViewController.m in Sources */,
1797CB8E1E81BB4F00D9F729 /* BFRImageTransitionAnimator.m in Sources */,
1797CB911E81BBB200D9F729 /* ThirdViewController.m in Sources */,
95D4797D1F97C348001E54D4 /* FifthViewController.m in Sources */,
944B4DEA1BFFC0E300B9BF87 /* BFRImageViewController.m in Sources */,
944B4DB31BFFC0C000B9BF87 /* AppDelegate.m in Sources */,
171F4AD01E96BE0500F4AF01 /* BFRBackLoadedImageSource.m in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
7 changes: 6 additions & 1 deletion BFRImageViewerDemo/BFRImageViewer/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#import "SecondViewController.h"
#import "ThirdViewController.h"
#import "FourthViewController.h"
#import "FifthViewController.h"

@interface AppDelegate ()

Expand All @@ -24,7 +25,11 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(

UITabBarController *tabVC = [UITabBarController new];
tabVC.view.backgroundColor = [UIColor whiteColor];
tabVC.viewControllers = @[[FirstViewController new], [SecondViewController new], [ThirdViewController new], [FourthViewController new]];
tabVC.viewControllers = @[[FirstViewController new],
[SecondViewController new],
[ThirdViewController new],
[FourthViewController new],
[FifthViewController new]];

self.window.rootViewController = tabVC;
[self.window makeKeyAndVisible];
Expand Down
13 changes: 13 additions & 0 deletions BFRImageViewerDemo/BFRImageViewer/FifthViewController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// FifthViewController.h
// BFRImageViewer
//
// Created by Omer Emre Aslan on 18.10.2017.
// Copyright © 2017 Andrew Yates. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface FifthViewController : UIViewController

@end
164 changes: 164 additions & 0 deletions BFRImageViewerDemo/BFRImageViewer/FifthViewController.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
//
// FifthViewController.m
// BFRImageViewer
//
// Created by Omer Emre Aslan on 18.10.2017.
// Copyright © 2017 Andrew Yates. All rights reserved.
//

#import <Photos/Photos.h>
#import "FifthViewController.h"
#import "BFRImageViewController.h"

@interface FifthViewController () <UIViewControllerPreviewingDelegate>

@end

@implementation FifthViewController

- (instancetype) init {
if (self = [super init]) {
self.title = @"Live Photo";
}

return self;
}

- (void)viewDidLoad {
[super viewDidLoad];

[self check3DTouch];

[self addImageButtonToView];
}

#pragma mark - 3D Touch
- (void)check3DTouch {
if ([self.traitCollection respondsToSelector:@selector(forceTouchCapability)] && self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
[self registerForPreviewingWithDelegate:self sourceView:self.view];
}
}

- (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location {
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];

if (status == PHAuthorizationStatusAuthorized) {
return [self imageViewControllerForLivePhotoDisableAutoplay:NO];
} else {
[self showAuthorizationAlertViewControllerAnimated:YES];
return nil;
}
}

- (void)previewingContext:(id<UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit {
[self presentViewController:viewControllerToCommit animated:YES completion:nil];
}

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
if ([self.traitCollection respondsToSelector:@selector(forceTouchCapability)] && self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
[self check3DTouch];
}
}

#pragma mark - Misc
- (void)addImageButtonToView {
UIButton *openImageFromURL = [UIButton buttonWithType:UIButtonTypeRoundedRect];
openImageFromURL.translatesAutoresizingMaskIntoConstraints = NO;
[openImageFromURL setTitle:@"Open Image" forState:UIControlStateNormal];
[openImageFromURL addTarget:self
action:@selector(openImage:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:openImageFromURL];
[openImageFromURL.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor].active = YES;
[openImageFromURL.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor].active = YES;
}

#pragma mark - Actions

- (void)openImage:(UIButton *)sender {
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];

if (status == PHAuthorizationStatusAuthorized) {
BFRImageViewController *imageViewController = [self
imageViewControllerForLivePhotoDisableAutoplay:YES];
[self presentViewController:imageViewController
animated:YES
completion:nil];
} else {
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusAuthorized) {
BFRImageViewController *imageViewController = [self imageViewControllerForLivePhotoDisableAutoplay:YES];
[self presentViewController:imageViewController
animated:YES
completion:nil];
} else {
[self showAuthorizationAlertViewControllerAnimated:YES];
}
}];
}

}

- (void)showAuthorizationAlertViewControllerAnimated:(BOOL)isAnimated {
UIAlertController *controller = [UIAlertController
alertControllerWithTitle:NSLocalizedString(@"Authorization Failed!", nil)
message:NSLocalizedString(@"In order to access live photo feature, please allow authorization on Settings.", nil)
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *closeAction = [UIAlertAction
actionWithTitle:NSLocalizedString(@"Close", nil)
style:UIAlertActionStyleDefault
handler:nil];
[controller addAction:closeAction];

[self presentViewController:controller
animated:isAnimated
completion:nil];
}

- (BFRImageViewController *)imageViewControllerForLivePhotoDisableAutoplay:(BOOL)shouldDisableAutoPlay {
PHFetchOptions *options = [[PHFetchOptions alloc] init];
options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]];
options.predicate = [NSPredicate predicateWithFormat:@"mediaType == %d", PHAssetMediaTypeImage];
options.predicate = [NSPredicate predicateWithFormat:@"mediaSubtype == %d", PHAssetMediaSubtypePhotoLive];
options.includeAllBurstAssets = NO;
PHFetchResult *allLivePhotos = [PHAsset fetchAssetsWithOptions:options];

NSMutableArray *livePhotosToShow = [NSMutableArray new];

if (allLivePhotos.count > 0) {
NSInteger maxResults = 4;
NSInteger currentFetchCount = 0;

for (PHFetchResult *result in allLivePhotos) {
if (currentFetchCount == maxResults) {
break;
}

[livePhotosToShow addObject:result];
currentFetchCount++;
}

BFRImageViewController *viewController = [[BFRImageViewController alloc]
initWithImageSource:[livePhotosToShow copy]];
viewController.disableAutoplayForLivePhoto = shouldDisableAutoPlay;
return viewController;
} else {
UIAlertController *controller = [UIAlertController
alertControllerWithTitle:@"No Live Photos"
message:@"There doesn't appear to be any live photos on your device."
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *closeAction = [UIAlertAction
actionWithTitle:NSLocalizedString(@"Close", nil)
style:UIAlertActionStyleDefault
handler:nil];
[controller addAction:closeAction];

[self presentViewController:controller
animated:YES
completion:nil];

return nil;
}
}

@end
2 changes: 2 additions & 0 deletions BFRImageViewerDemo/BFRImageViewer/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPhotoLibraryUsageDescription</key>
<string>The app will open an image from your library.</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
Expand Down