Skip to content

fix 点击图片放大时图片抖动的严重 bug #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
235 changes: 118 additions & 117 deletions CXPhotoBrowser/CXZoomingScrollView.m
Original file line number Diff line number Diff line change
Expand Up @@ -39,63 +39,63 @@ - (id)initWithPhotoBrowser:(CXPhotoBrowser *)browser
// Delegate
self.photoBrowser = browser;

// Tap view for background
_tapView = [[CXTapDetectingView alloc] initWithFrame:self.bounds];
_tapView.tapDelegate = self;
_tapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
_tapView.backgroundColor = [UIColor blackColor];
[self addSubview:_tapView];
// Image view
_photoImageView = [[CXTapDetectingImageView alloc] initWithFrame:CGRectZero];
_photoImageView.tapDelegate = self;
_photoImageView.contentMode = UIViewContentModeCenter;
_photoImageView.backgroundColor = [UIColor blackColor];
[self addSubview:_photoImageView];
// Setup
self.backgroundColor = [UIColor blackColor];
self.delegate = self;
self.showsHorizontalScrollIndicator = NO;
self.showsVerticalScrollIndicator = NO;
self.decelerationRate = UIScrollViewDecelerationRateFast;
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
// Tap view for background
_tapView = [[CXTapDetectingView alloc] initWithFrame:self.bounds];
_tapView.tapDelegate = self;
_tapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
_tapView.backgroundColor = [UIColor blackColor];
[self addSubview:_tapView];
// Image view
_photoImageView = [[CXTapDetectingImageView alloc] initWithFrame:CGRectZero];
_photoImageView.tapDelegate = self;
_photoImageView.contentMode = UIViewContentModeCenter;
_photoImageView.backgroundColor = [UIColor blackColor];
[self addSubview:_photoImageView];
// Setup
self.backgroundColor = [UIColor blackColor];
self.delegate = self;
self.showsHorizontalScrollIndicator = NO;
self.showsVerticalScrollIndicator = NO;
self.decelerationRate = UIScrollViewDecelerationRateFast;
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
}
return self;
}

- (void)layoutSubviews {

// Update tap view frame
_tapView.frame = self.bounds;

// Super
[super layoutSubviews];

// Center the image as it becomes smaller than the size of the screen
CGSize boundsSize = self.bounds.size;

// Update tap view frame
_tapView.frame = self.bounds;

// Super
[super layoutSubviews];

_photoImageView.frame = [self getCenterFrame];
}

- (CGRect)getCenterFrame
{
CGSize boundsSize = [UIScreen mainScreen].bounds.size;
CGRect frameToCenter = _photoImageView.frame;


// Horizontally
if (frameToCenter.size.width < boundsSize.width) {
frameToCenter.origin.x = floorf((boundsSize.width - frameToCenter.size.width) / 2.0);
} else {
} else {
frameToCenter.origin.x = 0;
}
}

// Vertically
if (frameToCenter.size.height < boundsSize.height) {
frameToCenter.origin.y = floorf((boundsSize.height - frameToCenter.size.height) / 2.0);
} else {
} else {
frameToCenter.origin.y = 0;
}

// Center
if (!CGRectEqualToRect(_photoImageView.frame, frameToCenter))
{
_photoImageView.frame = frameToCenter;
}
}

return frameToCenter;
}

#pragma mark - Setter
Expand Down Expand Up @@ -143,45 +143,45 @@ - (void)displayImage
if (_photo && !_photoImageView.image)
{
[self setUserInteractionEnabled:YES];
// Reset
self.maximumZoomScale = 1;
self.minimumZoomScale = 1;
self.zoomScale = 1;
self.contentSize = CGSizeMake(0, 0);
// Get image from browser as it handles ordering of fetching
UIImage *img = [self.photoBrowser imageForPhoto:_photo];
if (img)
// Reset
self.maximumZoomScale = 1;
self.minimumZoomScale = 1;
self.zoomScale = 1;
self.contentSize = CGSizeMake(0, 0);
// Get image from browser as it handles ordering of fetching
UIImage *img = [self.photoBrowser imageForPhoto:_photo];
if (img)
{
id photoBrowserDelegate = self.photoBrowser.delegate;
if (photoBrowserDelegate && [photoBrowserDelegate respondsToSelector:@selector(photoBrowser:didFinishLoadingWithCurrentImage:)]) {
[photoBrowserDelegate photoBrowser:self.photoBrowser didFinishLoadingWithCurrentImage:img];
}

[_photoLoadingView removeFromSuperview];
// Set image
_photoImageView.image = img;
_photoImageView.hidden = NO;

// Setup photo frame
CGRect photoImageViewFrame;
photoImageViewFrame.origin = CGPointZero;
photoImageViewFrame.size = img.size;
_photoImageView.frame = photoImageViewFrame;
self.contentSize = photoImageViewFrame.size;
// Set image
_photoImageView.image = img;
_photoImageView.hidden = NO;

// Setup photo frame
CGRect photoImageViewFrame;
photoImageViewFrame.origin = CGPointZero;
photoImageViewFrame.size = img.size;
_photoImageView.frame = photoImageViewFrame;
self.contentSize = photoImageViewFrame.size;

// Set zoom to minimum zoom
[self setMaxMinZoomScalesForCurrentBounds];

// Set zoom to minimum zoom
[self setMaxMinZoomScalesForCurrentBounds];

}
}
else
{
// Hide image view
// Hide image view
[self layoutPhotoLoadingView];
_photoImageView.hidden = YES;
}
[self setNeedsLayout];
}
_photoImageView.hidden = YES;
}
[self setNeedsLayout];
}
}

- (void)displayImageFailure
Expand All @@ -197,44 +197,44 @@ - (void)displayImageFailure
- (void)setMaxMinZoomScalesForCurrentBounds
{
// Reset
self.maximumZoomScale = 1;
self.minimumZoomScale = 1;
self.zoomScale = 1;
// Bail
if (_photoImageView.image == nil) return;
// Sizes
self.maximumZoomScale = 1;
self.minimumZoomScale = 1;
self.zoomScale = 1;
// Bail
if (_photoImageView.image == nil) return;
// Sizes
CGSize boundsSize = self.bounds.size;
CGSize imageSize = _photoImageView.frame.size;

// Calculate Min
CGFloat xScale = boundsSize.width / imageSize.width; // the scale needed to perfectly fit the image width-wise
CGFloat yScale = boundsSize.height / imageSize.height; // the scale needed to perfectly fit the image height-wise
CGFloat minScale = MIN(xScale, yScale); // use minimum of these to allow the image to become fully visible

// If image is smaller than the screen then ensure we show it at
// min scale of 1
if (xScale > 1 && yScale > 1) {
minScale = 1.0;
}

// Calculate Max
CGFloat maxScale = 2.0; // Allow double scale
// If image is smaller than the screen then ensure we show it at
// min scale of 1
if (xScale > 1 && yScale > 1) {
minScale = 1.0;
}

// Calculate Max
CGFloat maxScale = 2.0; // Allow double scale
// on high resolution screens we have double the pixel density, so we will be seeing every pixel if we limit the
// maximum zoom scale to 0.5.
if ([UIScreen instancesRespondToSelector:@selector(scale)]) {
maxScale = maxScale / [[UIScreen mainScreen] scale];
}
// Set
self.maximumZoomScale = maxScale;
self.minimumZoomScale = minScale;
self.zoomScale = minScale;
zoomScaleFromInit = minScale;
// Reset position
_photoImageView.frame = CGRectMake(0, 0, _photoImageView.frame.size.width, _photoImageView.frame.size.height);
[self setNeedsLayout];
if ([UIScreen instancesRespondToSelector:@selector(scale)]) {
maxScale = maxScale / [[UIScreen mainScreen] scale];
}
// Set
self.maximumZoomScale = maxScale;
self.minimumZoomScale = minScale;
self.zoomScale = minScale;
zoomScaleFromInit = minScale;
// Reset position
_photoImageView.frame = CGRectMake(0, 0, _photoImageView.frame.size.width, _photoImageView.frame.size.height);
[self setNeedsLayout];
}

- (void)prepareForReuse
Expand All @@ -245,12 +245,12 @@ - (void)prepareForReuse

#pragma mark - UIScrollViewDelegate
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return _photoImageView;
return _photoImageView;
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{

}

- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view
Expand All @@ -261,6 +261,7 @@ - (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
shouldSupportedPanGesture = ((self.zoomScale == zoomScaleFromInit) && self.isPhotoSupportedPanGesture);
_photoImageView.frame = [self getCenterFrame];
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
Expand All @@ -278,30 +279,30 @@ - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

- (void)handleImageViewSingleTap:(CGPoint)touchPoint {

[_photoBrowser performSelector:@selector(toggleControls) withObject:nil afterDelay:0.2];
[_photoBrowser performSelector:@selector(toggleControls) withObject:nil afterDelay:0.2];
}

- (void)handleImageViewDoubleTap:(CGPoint)touchPoint {
// Cancel any single tap handling
[NSObject cancelPreviousPerformRequestsWithTarget:_photoBrowser];
// Zoom
if (self.zoomScale == self.maximumZoomScale) {
// Zoom out
// Cancel any single tap handling
[NSObject cancelPreviousPerformRequestsWithTarget:_photoBrowser];
// Zoom
if (self.zoomScale == self.maximumZoomScale) {
// Zoom out
[_photoBrowser setToolBarViewsHidden:NO animated:YES];
[self setZoomScale:self.minimumZoomScale animated:YES];
} else {
// Zoom in
[self setZoomScale:self.minimumZoomScale animated:YES];
} else {
// Zoom in
[_photoBrowser setToolBarViewsHidden:YES animated:YES];
[self zoomToRect:CGRectMake(touchPoint.x, touchPoint.y, 1, 1) animated:YES];
}
// Delay controls
[self zoomToRect:CGRectMake(touchPoint.x, touchPoint.y, 1, 1) animated:YES];
}
// Delay controls
}
#pragma mark - CXTapDetectingImageViewDelegate
- (void)imageView:(UIImageView *)imageView singleTapDetected:(UITouch *)touch {
Expand Down