Skip to content

Commit

Permalink
Merge pull request nytimes#158 from NYTimes/develop
Browse files Browse the repository at this point in the history
Merge develop into master for v1.1.0
  • Loading branch information
cdzombak committed Feb 3, 2016
2 parents f2cff75 + 4b52b25 commit a3c82da
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 26 deletions.
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
## `develop`

Changes for users of the library currently on `develop`:

_This space intentionally left blank._

## [1.1.0](https://github.com/NYTimes/NYTPhotoViewer/releases/tag/1.1.0)

Changes for users of the library in 1.1.0:

- Add a delegate method to allow customizing navigation bar title text ([#142](https://github.com/NYTimes/NYTPhotoViewer/pull/142), [#151](https://github.com/NYTimes/NYTPhotoViewer/pull/151), [#154](https://github.com/NYTimes/NYTPhotoViewer/pull/154))
- Add documentation clarifying `NYTPhoto.image` vs `.imageData` properties; add a warning if you’re doing something wrong ([#153](https://github.com/NYTimes/NYTPhotoViewer/pull/152))
- Add `delegate` to the designated initializer ([#155](https://github.com/NYTimes/NYTPhotoViewer/pull/155))
- Fix overlay view animating out and back when a view controller presented atop `NYTPhotosViewController` is dismissed ([#156](https://github.com/NYTimes/NYTPhotoViewer/pull/156))

## [1.0.1](https://github.com/NYTimes/NYTPhotoViewer/releases/tag/1.0.1)

Changes for users of the library currently on `develop`:
Changes for users of the library in 1.0.1:

- Fixes for incorrect logic determining whether to send delegate messages about `PhotosViewController` dismissal ([#130](https://github.com/NYTimes/NYTPhotoViewer/pull/130), [#137](https://github.com/NYTimes/NYTPhotoViewer/pull/137))
- Avoid testing floats for equality in PhotoViewController ([#135](https://github.com/NYTimes/NYTPhotoViewer/pull/135))
Expand Down
3 changes: 2 additions & 1 deletion Documentation/Release Process.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ _While tagging a new version of a library and pushing it to CocoaPods is concept
- When reviewing the commit history, searching for “Merge pull request” helps find changes which should appear in [the `CHANGELOG`](https://github.com/NYTimes/NYTPhotoViewer/blob/develop/CHANGELOG.md).
- Update any other documentation which still needs to be updated, given those changes.
- Create a pull request merging [`develop` into `master`](https://github.com/NYTimes/NYTPhotoViewer/compare/master...develop). Merge it yourself, immediately.
- Create a Github release, using the new version number (eg. `1.0.0`) as the tag, and the merge commit into `master` as the target. Copy [the `CHANGELOG`](https://raw.githubusercontent.com/NYTimes/NYTPhotoViewer/develop/CHANGELOG.md)’s Markdown content for this release into the Github release.
- Create a [Github release](https://github.com/NYTimes/NYTPhotoViewer/releases), using the new version number (eg. `1.0.0`) as the tag, and the merge commit into `master` as the target. Copy [the `CHANGELOG`](https://raw.githubusercontent.com/NYTimes/NYTPhotoViewer/develop/CHANGELOG.md)’s Markdown content for this release into the Github release.
- Push the new Podspec to Cocoapods Trunk: `pod trunk push NYTPhotoViewer.podspec`
- Ensure your local clone is up-to-date before this push.

## CocoaPods Trunk Setup

Expand Down
11 changes: 9 additions & 2 deletions Example/NYTPhotoViewer/NYTViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ - (void)updateImagesOnPhotosViewController:(NYTPhotosViewController *)photosView
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(updateImageDelay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
for (NYTExamplePhoto *photo in photos) {
if (!photo.image && !photo.imageData) {
// Photo credit: Nic Lehoux
photo.image = [UIImage imageNamed:@"NYTimesBuilding"];
[photosViewController updateImageForPhoto:photo];
}
Expand Down Expand Up @@ -99,7 +98,7 @@ + (NSArray *)newTestPhotos {

photo.attributedCaptionTitle = [[NSAttributedString alloc] initWithString:@(i + 1).stringValue attributes:@{NSForegroundColorAttributeName: [UIColor whiteColor], NSFontAttributeName: [UIFont preferredFontForTextStyle:UIFontTextStyleBody]}];
photo.attributedCaptionSummary = [[NSAttributedString alloc] initWithString:caption attributes:@{NSForegroundColorAttributeName: [UIColor lightGrayColor], NSFontAttributeName: [UIFont preferredFontForTextStyle:UIFontTextStyleBody]}];
photo.attributedCaptionCredit = [[NSAttributedString alloc] initWithString:@"credit" attributes:@{NSForegroundColorAttributeName: [UIColor grayColor], NSFontAttributeName: [UIFont preferredFontForTextStyle:UIFontTextStyleCaption1]}];
photo.attributedCaptionCredit = [[NSAttributedString alloc] initWithString:@"NYT Building Photo Credit: Nic Lehoux" attributes:@{NSForegroundColorAttributeName: [UIColor grayColor], NSFontAttributeName: [UIFont preferredFontForTextStyle:UIFontTextStyleCaption1]}];

[photos addObject:photo];
}
Expand Down Expand Up @@ -156,6 +155,14 @@ - (NSDictionary *)photosViewController:(NYTPhotosViewController *)photosViewCont
return nil;
}

- (NSString *)photosViewController:(NYTPhotosViewController *)photosViewController titleForPhoto:(id<NYTPhoto>)photo atIndex:(NSUInteger)photoIndex totalPhotoCount:(NSUInteger)totalPhotoCount {
if ([photo isEqual:self.photos[NYTViewControllerPhotoIndexCustomEverything]]) {
return [NSString stringWithFormat:@"%lu/%lu", (unsigned long)photoIndex+1, (unsigned long)totalPhotoCount];
}

return nil;
}

- (void)photosViewController:(NYTPhotosViewController *)photosViewController didNavigateToPhoto:(id <NYTPhoto>)photo atIndex:(NSUInteger)photoIndex {
NSLog(@"Did Navigate To Photo: %@ identifier: %lu", photo, (unsigned long)photoIndex);
}
Expand Down
33 changes: 29 additions & 4 deletions Example/Tests/NYTPhotosViewControllerTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -136,22 +136,47 @@ - (void)testRightBarButtonItemsAreNilAfterSettingToNil {
XCTAssertNil(photosViewController.rightBarButtonItems);
}

- (void)testConvenienceInitializerAcceptsNil {
- (void)testOneArgConvenienceInitializerAcceptsNil {
XCTAssertNoThrow([[NYTPhotosViewController alloc] initWithPhotos:nil]);
}

- (void)testDesignatedInitializerAcceptsNilForPhotosParameter {
- (void)testTwoArgConvenienceInitializerAcceptsNilForPhotosParameter {
XCTAssertNoThrow([[NYTPhotosViewController alloc] initWithPhotos:nil initialPhoto:[[NYTExamplePhoto alloc] init]]);
}

- (void)testDesignatedInitializerAcceptsNilForInitialPhotoParameter {
- (void)testTwoArgConvenienceInitializerAcceptsNilForInitialPhotoParameter {
XCTAssertNoThrow([[NYTPhotosViewController alloc] initWithPhotos:[self newTestPhotos] initialPhoto:nil]);
}

- (void)testDesignatedInitializerAcceptsNilForBothParameters {
- (void)testTwoArgConvenienceInitializerAcceptsNilForBothParameters {
XCTAssertNoThrow([[NYTPhotosViewController alloc] initWithPhotos:nil initialPhoto:nil]);
}

- (void)testDesignatedInitializerAcceptsNilForPhotosParameter {
id delegateMock = OCMProtocolMock(@protocol(NYTPhotosViewControllerDelegate));
XCTAssertNoThrow([[NYTPhotosViewController alloc] initWithPhotos:nil initialPhoto:[NYTExamplePhoto new] delegate:delegateMock]);
}

- (void)testDesignatedInitializerAcceptsNilForInitialPhotoParameter {
id delegateMock = OCMProtocolMock(@protocol(NYTPhotosViewControllerDelegate));
XCTAssertNoThrow([[NYTPhotosViewController alloc] initWithPhotos:[self newTestPhotos] initialPhoto:nil delegate:delegateMock]);
}

- (void)testDesignatedInitializerAcceptsNilForDelegateParameter {
XCTAssertNoThrow([[NYTPhotosViewController alloc] initWithPhotos:[self newTestPhotos] initialPhoto:[NYTExamplePhoto new] delegate:nil]);
}

- (void)testDesignatedInitializerAcceptsNilForAllParameters {
XCTAssertNoThrow([[NYTPhotosViewController alloc] initWithPhotos:nil initialPhoto:nil delegate:nil]);
}

- (void)testDesignatedInitializerSetsDelegate {
id delegateMock = OCMProtocolMock(@protocol(NYTPhotosViewControllerDelegate));
NYTPhotosViewController *sut = [[NYTPhotosViewController alloc] initWithPhotos:[self newTestPhotos] initialPhoto:nil delegate:delegateMock];

XCTAssertEqual(sut.delegate, delegateMock);
}

- (void)testDisplayPhotoAcceptsNil {
NYTPhotosViewController *photosViewController = [[NYTPhotosViewController alloc] initWithPhotos:[self newTestPhotos]];
XCTAssertNoThrow([photosViewController displayPhoto:nil animated:NO]);
Expand Down
2 changes: 1 addition & 1 deletion NYTPhotoViewer.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "NYTPhotoViewer"
s.version = "1.0.1"
s.version = "1.1.0"

s.description = <<-DESC
NYTPhotoViewer is a slideshow and image viewer that includes double tap to zoom, captions, support for multiple images, interactive flick to dismiss, animated zooming presentation, and more.
Expand Down
29 changes: 27 additions & 2 deletions Pod/Classes/ios/NYTPhotosViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,23 +89,34 @@ extern NSString * const NYTPhotosViewControllerDidDismissNotification;
@property (nonatomic, weak, nullable) id <NYTPhotosViewControllerDelegate> delegate;

/**
* A convenience initializer that calls `initWithPhotos:initialPhoto:`, passing the first photo as the `initialPhoto` argument.
* A convenience initializer that calls `initWithPhotos:initialPhoto:delegate:`, passing the first photo as the `initialPhoto` argument, and `nil` as the `delegate` argument.
*
* @param photos An array of objects conforming to the `NYTPhoto` protocol.
*
* @return A fully initialized object.
*/
- (instancetype)initWithPhotos:(NSArray <id <NYTPhoto>> * _Nullable)photos;

/**
* A convenience initializer that calls `initWithPhotos:initialPhoto:delegate:`, passing `nil` as the `delegate` argument.
*
* @param photos An array of objects conforming to the `NYTPhoto` protocol.
* @param initialPhoto The photo to display initially. Must be contained within the `photos` array. If `nil` or not within the `photos` array, the first photo within the `photos` array will be displayed.
*
* @return A fully initialized object.
*/
- (instancetype)initWithPhotos:(NSArray <id <NYTPhoto>> * _Nullable)photos initialPhoto:(id <NYTPhoto> _Nullable)initialPhoto;

/**
* The designated initializer that stores the array of objects conforming to the `NYTPhoto` protocol for display, along with specifying an initial photo for display.
*
* @param photos An array of objects conforming to the `NYTPhoto` protocol.
* @param initialPhoto The photo to display initially. Must be contained within the `photos` array. If `nil` or not within the `photos` array, the first photo within the `photos` array will be displayed.
* @param delegate The delegate for this `NYTPhotosViewController`.
*
* @return A fully initialized object.
*/
- (instancetype)initWithPhotos:(NSArray <id <NYTPhoto>> * _Nullable)photos initialPhoto:(id <NYTPhoto> _Nullable)initialPhoto NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithPhotos:(NSArray <id <NYTPhoto>> * _Nullable)photos initialPhoto:(id <NYTPhoto> _Nullable)initialPhoto delegate:(nullable id <NYTPhotosViewControllerDelegate>)delegate NS_DESIGNATED_INITIALIZER;

/**
* Displays the specified photo. Can be called before the view controller is displayed. Calling with a photo not contained within the data source has no effect.
Expand Down Expand Up @@ -165,6 +176,20 @@ extern NSString * const NYTPhotosViewControllerDidDismissNotification;
*/
- (UIView * _Nullable)photosViewController:(NYTPhotosViewController *)photosViewController captionViewForPhoto:(id <NYTPhoto>)photo;

/**
* Returns a string to display as the title in the navigation-bar area for a photo.
*
* This small area of the screen is not intended to display a caption or similar information about the photo itself. (NYTPhotoViewer is designed to provide this information in the caption view, and as such the `NYTPhoto` protocol provides properties for the title, summary, and credit for each photo.) Instead, consider using this delegate method to customize how your app displays the user's progress through a set of photos.
*
* @param photosViewController The `NYTPhotosViewController` instance that sent the delegate message.
* @param photo The photo object for which to display the title.
* @param photoIndex The index of the photo.
* @param totalPhotoCount The number of photos being displayed by the photo viewer.
*
* @return The text to display as the navigation-item title for the given photo. Return `nil` to show a default title like "1 of 4" indicating progress in a slideshow, or an empty string to hide this text entirely.
*/
- (NSString * _Nullable)photosViewController:(NYTPhotosViewController *)photosViewController titleForPhoto:(id <NYTPhoto>)photo atIndex:(NSUInteger)photoIndex totalPhotoCount:(NSUInteger)totalPhotoCount;

/**
* Returns a view to display while a photo is loading. Can be any `UIView` object, but is expected to respond to `sizeToFit` appropriately. This view will be sized and centered in the blank area, and hidden when the photo image is loaded.
*
Expand Down
41 changes: 28 additions & 13 deletions Pod/Classes/ios/NYTPhotosViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];

if (self) {
[self commonInitWithPhotos:nil initialPhoto:nil];
[self commonInitWithPhotos:nil initialPhoto:nil delegate:nil];
}

return self;
Expand Down Expand Up @@ -156,21 +156,27 @@ - (void)dismissViewControllerAnimated:(BOOL)animated completion:(void (^)(void))
#pragma mark - NYTPhotosViewController

- (instancetype)initWithPhotos:(NSArray *)photos {
return [self initWithPhotos:photos initialPhoto:photos.firstObject];
return [self initWithPhotos:photos initialPhoto:photos.firstObject delegate:nil];
}

- (instancetype)initWithPhotos:(NSArray *)photos initialPhoto:(id <NYTPhoto>)initialPhoto {
return [self initWithPhotos:photos initialPhoto:initialPhoto delegate:nil];
}

- (instancetype)initWithPhotos:(NSArray *)photos initialPhoto:(id <NYTPhoto>)initialPhoto delegate:(id<NYTPhotosViewControllerDelegate>)delegate {
self = [super initWithNibName:nil bundle:nil];

if (self) {
[self commonInitWithPhotos:photos initialPhoto:initialPhoto];
[self commonInitWithPhotos:photos initialPhoto:initialPhoto delegate:delegate];
}

return self;
}

- (void)commonInitWithPhotos:(NSArray *)photos initialPhoto:(id <NYTPhoto>)initialPhoto {
- (void)commonInitWithPhotos:(NSArray *)photos initialPhoto:(id <NYTPhoto>)initialPhoto delegate:(id<NYTPhotosViewControllerDelegate>)delegate {
_dataSource = [[NYTPhotosDataSource alloc] initWithPhotos:photos];
_delegate = delegate;

_panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(didPanWithGestureRecognizer:)];
_singleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didSingleTapWithGestureRecognizer:)];

Expand Down Expand Up @@ -219,16 +225,23 @@ - (void)addOverlayView {
[self setOverlayViewHidden:YES animated:NO];
}


- (void)updateOverlayInformation {
NSUInteger displayIndex = 1;
NSString *overlayTitle;

NSUInteger photoIndex = [self.dataSource indexOfPhoto:self.currentlyDisplayedPhoto];
if (photoIndex < self.dataSource.numberOfPhotos) {
displayIndex = photoIndex + 1;

if ([self.delegate respondsToSelector:@selector(photosViewController:titleForPhoto:atIndex:totalPhotoCount:)]) {
overlayTitle = [self.delegate photosViewController:self titleForPhoto:self.currentlyDisplayedPhoto atIndex:photoIndex totalPhotoCount:self.dataSource.numberOfPhotos];
}

NSString *overlayTitle;
if (self.dataSource.numberOfPhotos > 1) {
if (!overlayTitle && self.dataSource.numberOfPhotos > 1) {
NSUInteger displayIndex = 1;

if (photoIndex < self.dataSource.numberOfPhotos) {
displayIndex = photoIndex + 1;
}

overlayTitle = [NSString localizedStringWithFormat:NSLocalizedString(@"%lu of %lu", nil), (unsigned long)displayIndex, (unsigned long)self.dataSource.numberOfPhotos];
}

Expand Down Expand Up @@ -256,11 +269,8 @@ - (void)actionButtonTapped:(id)sender {
if ([self.delegate respondsToSelector:@selector(photosViewController:handleActionButtonTappedForPhoto:)]) {
clientDidHandle = [self.delegate photosViewController:self handleActionButtonTappedForPhoto:self.currentlyDisplayedPhoto];
}
#ifdef ANIMATED_GIF_SUPPORT
if (!clientDidHandle && (self.currentlyDisplayedPhoto.image || self.currentlyDisplayedPhoto.imageData)) {
#else
if (!clientDidHandle && self.currentlyDisplayedPhoto.image) {
#endif
UIImage *image = self.currentlyDisplayedPhoto.image ? self.currentlyDisplayedPhoto.image : [UIImage imageWithData:self.currentlyDisplayedPhoto.imageData];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[image] applicationActivities:nil];
activityViewController.popoverPresentationController.barButtonItem = sender;
Expand Down Expand Up @@ -351,6 +361,11 @@ - (void)didPanWithGestureRecognizer:(UIPanGestureRecognizer *)panGestureRecogniz
#pragma mark - View Controller Dismissal

- (void)dismissViewControllerAnimated:(BOOL)animated userInitiated:(BOOL)isUserInitiated completion:(void (^)(void))completion {
if (self.presentedViewController) {
[super dismissViewControllerAnimated:animated completion:completion];
return;
}

UIView *startingView;
if (self.currentlyDisplayedPhoto.image || self.currentlyDisplayedPhoto.placeholderImage || self.currentlyDisplayedPhoto.imageData) {
startingView = self.currentPhotoViewController.scalingImageView.imageView;
Expand Down
8 changes: 8 additions & 0 deletions Pod/Classes/ios/NYTScalingImageView.m
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,14 @@ - (void)updateImageData:(NSData *)imageData {
}

- (void)updateImage:(UIImage *)image imageData:(NSData *)imageData {
#ifdef DEBUG
#ifndef ANIMATED_GIF_SUPPORT
if (imageData != nil) {
NSLog(@"[NYTPhotoViewer] Warning! You're providing imageData for a photo, but NYTPhotoViewer was compiled without animated GIF support. You should use native UIImages for non-animated photos. See the NYTPhoto protocol documentation for discussion.");
}
#endif // ANIMATED_GIF_SUPPORT
#endif // DEBUG

UIImage *imageToUse = image ?: [UIImage imageWithData:imageData];

// Remove any transform currently applied by the scroll view zooming.
Expand Down
11 changes: 9 additions & 2 deletions Pod/Classes/ios/Protocols/NYTPhoto.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,24 @@ NS_ASSUME_NONNULL_BEGIN

/**
* The image to display.
*
* This property is used if and only if `-imageData` returns `nil`. Note, however, that returning `UIImage`s from this property whenever possible will result in better performance. See `-imageData`'s documentation for discussion.
*/
@property (nonatomic, readonly, nullable) UIImage *image;

/**
* The image data to display. This will be preferred over the `image` property.
* In case this is empty `image` will be used. The main advantage of using this is animated gif support.
* The image data to display.
*
* This property's value, if non-`nil`, is preferred over `-image`. This allows clients to provide image data for FLAnimatedImage when the library is compiled with `ANIMATED_GIF_SUPPORT` defined.
*
* Note that if you're working with a non-animated image, using a native `UIImage` will provide better performance. Therefore, it is recommended to return `nil` from this property unless this photo is an animated GIF.
*/
@property (nonatomic, readonly, nullable) NSData *imageData;

/**
* A placeholder image for display while the image is loading.
*
* This property is used if and only if `-imageData` returns `nil`.
*/
@property (nonatomic, readonly, nullable) UIImage *placeholderImage;

Expand Down

0 comments on commit a3c82da

Please sign in to comment.