IDMPhotoBrowserとは
- https://github.com/ideaismobile/IDMPhotoBrowser
- FacebookやtwitterのようなPhotoBrowserが実装されていて、MWPhotoBrowserの次に人気 http://cocoapods.wantedly.com/?q=photoBrowser
- 通信周りでは、MWPhotoBrowserはSDWebImageを使っていて、IDMPhotoBrowserはAFNetworking2系を使っている。
- usePopAnimationをYESにすると、Facebookが公開しているpopというanimationライブラリを使って画像の拡大ができる https://github.com/facebook/pop
IDMPhotoBrowserの仕組み
画像が拡大しながらモダルを開く
- windowに直接、黒い背景とクリックされたの画像を表示している
- その後、その画像をPhotoBrowserに合った大きさに拡大させる
- animationが終わったら、windowから黒い背景と画像を削除
- 表示の際のコードはこちら
- (void)performPresentAnimation {
self.view.alpha = 0.0f;
UIImage *imageFromView = _scaleImage ? _scaleImage : [self getImageFromView:_senderViewForAnimation];
imageFromView = [self rotateImageToCurrentOrientation:imageFromView];
_senderViewOriginalFrame = [_senderViewForAnimation.superview convertRect:_senderViewForAnimation.frame toView:nil];
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenBound.size.width;
CGFloat screenHeight = screenBound.size.height;
UIView *fadeView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, screenWidth, screenHeight)];
fadeView.backgroundColor = [UIColor clearColor];
[_applicationWindow addSubview:fadeView];
UIImageView *resizableImageView = [[UIImageView alloc] initWithImage:imageFromView];
resizableImageView.frame = _senderViewOriginalFrame;
resizableImageView.clipsToBounds = YES;
resizableImageView.contentMode = UIViewContentModeScaleAspectFill;
resizableImageView.backgroundColor = [UIColor colorWithWhite:(_useWhiteBackgroundColor) ? 1 : 0 alpha:1];
[_applicationWindow addSubview:resizableImageView];
_senderViewForAnimation.hidden = YES;
void (^completion)() = ^() {
self.view.alpha = 1.0f;
resizableImageView.backgroundColor = [UIColor colorWithWhite:(_useWhiteBackgroundColor) ? 1 : 0 alpha:1];
[fadeView removeFromSuperview];
[resizableImageView removeFromSuperview];
};
[UIView animateWithDuration:_animationDuration animations:^{
fadeView.backgroundColor = self.useWhiteBackgroundColor ? [UIColor whiteColor] : [UIColor blackColor];
} completion:nil];
float scaleFactor = (imageFromView ? imageFromView.size.width : screenWidth) / screenWidth;
CGRect finalImageViewFrame = CGRectMake(0, (screenHeight/2)-((imageFromView.size.height / scaleFactor)/2), screenWidth, imageFromView.size.height / scaleFactor);
if(_usePopAnimation)
{
[self animateView:resizableImageView
toFrame:finalImageViewFrame
completion:completion];
}
else
{
[UIView animateWithDuration:_animationDuration animations:^{
resizableImageView.layer.frame = finalImageViewFrame;
} completion:^(BOOL finished) {
completion();
}];
}
}
画像をドラッグすると画像が上下に移動する
- 画像を閉じる動作には、UIPanGestureRecognizer
- 横スクロールの動きの時は、UIPanGestureRecognizerのイベントは呼ばれない
- 40px以上上下にスクロールすると、doneボタンを押した時と同じ動作になる
- Doneのアクションの後は、開くときと同様の動作
- 実装箇所は以下の部分
- (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 - abs(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
{
if (_senderViewForAnimation && _currentPageIndex == _initalPageIndex) {
[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];
[UIView setAnimationDelegate:self];
[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];
[UIView setAnimationDelegate:self];
[scrollView setCenter:CGPointMake(finalX, finalY)];
[UIView commitAnimations];
}
}
}