ifish/Ifish/controllers/IfishYooseeFile/IfishYooseeHelper/KTPhotoBrowser/KTPhotoView.m

284 lines
9.0 KiB
Objective-C

//
// KTPhotoView.m
// Sample
//
// Created by Kirby Turner on 2/24/10.
// Copyright 2010 White Peak Software Inc. All rights reserved.
//
#import "KTPhotoView.h"
#import "KTPhotoScrollViewController.h"
#import <QuartzCore/QuartzCore.h>
@interface KTPhotoView (KTPrivateMethods)
- (void)loadSubviewsWithFrame:(CGRect)frame;
- (BOOL)isZoomed;
- (void)toggleChromeDisplay;
@end
@implementation KTPhotoView
@synthesize scroller = scroller_;
@synthesize index = index_;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setDelegate:self];
[self setMaximumZoomScale:5.0];
[self setShowsHorizontalScrollIndicator:NO];
[self setShowsVerticalScrollIndicator:NO];
[self loadSubviewsWithFrame:frame];
//保存图片到相册
UILongPressGestureRecognizer* longPressGes = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(gestureToLongPress:)];
[longPressGes setMinimumPressDuration:0.5];
[self addGestureRecognizer:longPressGes];
}
return self;
}
- (void)loadSubviewsWithFrame:(CGRect)frame
{
imageView_ = [[UIImageView alloc] initWithFrame:frame];
[imageView_ setContentMode:UIViewContentModeScaleAspectFit];
[self addSubview:imageView_];
}
-(void)gestureToLongPress:(UILongPressGestureRecognizer* )ges{//保存图片到相册
switch (ges.state) {
case UIGestureRecognizerStateEnded:
{
}
break;
case UIGestureRecognizerStateBegan:
{
// UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:nil
// delegate:self
// cancelButtonTitle:NSLocalizedString(@"cancel", nil)
// destructiveButtonTitle:NSLocalizedString(@"delete_photo", nil)
// otherButtonTitles:NSLocalizedString(@"save_to_photo", nil), nil];
//
UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:self
cancelButtonTitle:@"取消"
destructiveButtonTitle:@"删除图片"
otherButtonTitles:@"保存图片", nil];
// Show the sheet
[sheet showInView:self];
}
break;
default:
break;
}
}
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex{
if(buttonIndex==0){//删除照片
if (self.deleteImageDelegate) {
[self.deleteImageDelegate KTPhotoViewDeleteImage:self.index];
}
}else if (buttonIndex == 1){//保存图片到相册
UIImageWriteToSavedPhotosAlbum(imageView_.image, self, @selector(image:didFinishSavingWithError:contextInfo:), NULL);
}
}
- (void)image: (UIImage *) image didFinishSavingWithError: (NSError *) error contextInfo: (void *) contextInfo{//保存图片到相册
if(error != NULL){
//[self makeToast:NSLocalizedString(@"保存图片失败", nil)];
}else{
//[self makeToast:NSLocalizedString(@"保存图片成功", nil)];
}
}
- (void)setImage:(UIImage *)newImage
{
[imageView_ setImage:newImage];
}
- (void)layoutSubviews
{
[super layoutSubviews];
if ([self isZoomed] == NO && CGRectEqualToRect([self bounds], [imageView_ frame]) == NO) {
[imageView_ setFrame:[self bounds]];
}
}
- (void)toggleChromeDisplay
{
if (scroller_) {
[scroller_ toggleChromeDisplay];
}
}
- (BOOL)isZoomed
{
return !([self zoomScale] == [self minimumZoomScale]);
}
- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center
{
CGRect zoomRect;
// the zoom rect is in the content view's coordinates.
// At a zoom scale of 1.0, it would be the size of the imageScrollView's bounds.
// As the zoom scale decreases, so more content is visible, the size of the rect grows.
zoomRect.size.height = [self frame].size.height / scale;
zoomRect.size.width = [self frame].size.width / scale;
// choose an origin so as to get the right center.
zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0);
zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0);
return zoomRect;
}
- (void)zoomToLocation:(CGPoint)location
{
float newScale;
CGRect zoomRect;
if ([self isZoomed]) {
zoomRect = [self bounds];
} else {
newScale = [self maximumZoomScale];
zoomRect = [self zoomRectForScale:newScale withCenter:location];
}
[self zoomToRect:zoomRect animated:YES];
}
- (void)turnOffZoom
{
if ([self isZoomed]) {
[self zoomToLocation:CGPointZero];
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if ([touch view] == self) {
if ([touch tapCount] == 2) {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(toggleChromeDisplay) object:nil];
[self zoomToLocation:[touch locationInView:self]];
}
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if ([touch view] == self) {
if ([touch tapCount] == 1) {
[self performSelector:@selector(toggleChromeDisplay) withObject:nil afterDelay:0.5];
}
}
}
#pragma mark -
#pragma mark UIScrollViewDelegate Methods
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
UIView *viewToZoom = imageView_;
return viewToZoom;
}
#pragma mark -
#pragma mark Methods called during rotation to preserve the zoomScale and the visible portion of the image
- (void)setMaxMinZoomScalesForCurrentBounds
{
CGSize boundsSize = self.bounds.size;
CGSize imageSize = imageView_.bounds.size;
// calculate min/max zoomscale
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
// 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.
CGFloat maxScale = 1.0 / [[UIScreen mainScreen] scale];
// don't let minScale exceed maxScale. (If the image is smaller than the screen, we don't want to force it to be zoomed.)
if (minScale > maxScale) {
minScale = maxScale;
}
self.maximumZoomScale = maxScale;
self.minimumZoomScale = minScale;
}
// returns the center point, in image coordinate space, to try to restore after rotation.
- (CGPoint)pointToCenterAfterRotation
{
CGPoint boundsCenter = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
return [self convertPoint:boundsCenter toView:imageView_];
}
// returns the zoom scale to attempt to restore after rotation.
- (CGFloat)scaleToRestoreAfterRotation
{
CGFloat contentScale = self.zoomScale;
// If we're at the minimum zoom scale, preserve that by returning 0, which will be converted to the minimum
// allowable scale when the scale is restored.
if (contentScale <= self.minimumZoomScale + FLT_EPSILON)
contentScale = 0;
return contentScale;
}
- (CGPoint)maximumContentOffset
{
CGSize contentSize = self.contentSize;
CGSize boundsSize = self.bounds.size;
return CGPointMake(contentSize.width - boundsSize.width, contentSize.height - boundsSize.height);
}
- (CGPoint)minimumContentOffset
{
return CGPointZero;
}
// Adjusts content offset and scale to try to preserve the old zoomscale and center.
- (void)restoreCenterPoint:(CGPoint)oldCenter scale:(CGFloat)oldScale
{
// Step 1: restore zoom scale, first making sure it is within the allowable range.
self.zoomScale = MIN(self.maximumZoomScale, MAX(self.minimumZoomScale, oldScale));
// Step 2: restore center point, first making sure it is within the allowable range.
// 2a: convert our desired center point back to our own coordinate space
CGPoint boundsCenter = [self convertPoint:oldCenter fromView:imageView_];
// 2b: calculate the content offset that would yield that center point
CGPoint offset = CGPointMake(boundsCenter.x - self.bounds.size.width / 2.0,
boundsCenter.y - self.bounds.size.height / 2.0);
// 2c: restore offset, adjusted to be within the allowable range
CGPoint maxOffset = [self maximumContentOffset];
CGPoint minOffset = [self minimumContentOffset];
offset.x = MAX(minOffset.x, MIN(maxOffset.x, offset.x));
offset.y = MAX(minOffset.y, MIN(maxOffset.y, offset.y));
self.contentOffset = offset;
}
@end