ios 图片拖拽,捏,双击放大缩小,以及保存到相册

图片拖拽,放大缩小原来是可以不用自己写算法的,直接用UIscrollView即可实现。

保存相册就比较简单了。

比较麻烦的地方:

捏,双击等动作形成的放大、缩小效果需要准确定位。

h文件:

//
//  DetailPopStarView.h
//  Gukw
//

#import <UIKit/UIKit.h>
#import "AsyncImageView.h"

@interface DetailPopStarView : UIView<UIScrollViewDelegate>
@property (nonatomic) NSString *url;
@property (nonatomic) AsyncImageView *imgView;
@property (nonatomic) CGFloat width;
@property (nonatomic) CGFloat height;
@property (nonatomic) BOOL isTwiceTaping;
@property (nonatomic) BOOL isDoubleTapingForZoom;
@property (nonatomic) CGFloat currentScale;
@property (nonatomic) CGFloat offsetY;
@property (nonatomic) UIScrollView *scrollView;
@property (nonatomic) UIActivityIndicatorView *activityIndicatorView;
@property (nonatomic) CGFloat touchX;
@property (nonatomic) CGFloat touchY;

-(void) draw;
@end

m文件:

//
//  DetailPopStarView.m
//
//

#import "DetailPopStarView.h"
#import "commonFunctions.h"

#define kScreenWidth  320.0
#define kScreenHeight  460.0
#define kMaxZoom 3.0

@implementation DetailPopStarView

@synthesize imgView = _imgView;
@synthesize url = _url;
@synthesize width = _width;
@synthesize height = _height;
@synthesize activityIndicatorView = _activityIndicatorView;
@synthesize isTwiceTaping = _isTwiceTaping;
@synthesize scrollView = _scrollView;
@synthesize currentScale = _currentScale;
@synthesize isDoubleTapingForZoom = _isDoubleTapingForZoom;
@synthesize  touchX = _touchX;
@synthesize  touchY = _touchY;
@synthesize offsetY = _offsetY;


- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}


// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{

}

- (void) draw{
    self.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight);
    self.backgroundColor = [UIColor blackColor];
    self.alpha = 0.0;

    _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight)];
    [self addSubview:_scrollView];
    _scrollView.delegate = self;
    _scrollView.maximumZoomScale = 5.0;
    CGFloat ratio = _width/_height*kScreenHeight/kScreenWidth;
    CGFloat min = MIN(ratio, 1.0);
    _scrollView.minimumZoomScale = min;
    
    CGFloat height = _height /_width * kScreenWidth;
    _imgView = [[AsyncImageView alloc] initWithFrame:CGRectMake(_scrollView.contentOffset.x+100, _scrollView.contentOffset.y+230, 10, 10)];
    [_imgView loadImage:_url];
    
    CGFloat y = (kScreenHeight - height)/2.0;
    _offsetY = 0.0-y;
    _scrollView.contentSize = CGSizeMake(kScreenWidth, height);
    [_scrollView addSubview:_imgView];
    _scrollView.contentOffset = CGPointMake(0, 0.0-y);
    
    [UIView animateWithDuration:0.6
        delay:0.0
        options: UIViewAnimationCurveEaseOut
        animations:^{
            _imgView.frame = CGRectMake(0, 0, kScreenWidth, height);  
            self.alpha = 1.0;
        } 
        completion:^(BOOL finished){
        }
    ];
    
    
    UITapGestureRecognizer *tapImgView = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapImgViewHandle)];
    tapImgView.numberOfTapsRequired = 1;
    tapImgView.numberOfTouchesRequired = 1;
    [self addGestureRecognizer:tapImgView];
    
    UITapGestureRecognizer *tapImgViewTwice = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapImgViewHandleTwice:)];
    tapImgViewTwice.numberOfTapsRequired = 2;
    tapImgViewTwice.numberOfTouchesRequired = 1;
    [self addGestureRecognizer:tapImgViewTwice];
    [tapImgView requireGestureRecognizerToFail:tapImgViewTwice];

    
    
    UITapGestureRecognizer *saveTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(saveTapHandler)];
    UIButton *save = [commonFunctions generateImage:@"save-pic-button.png" hover:@"save-pic-button-hover.png" withX:245 withY:420];
    [save addGestureRecognizer:saveTap];
    [self addSubview:save];
    
    _activityIndicatorView = [commonFunctions generateActivityIndicatorView];
    [self addSubview:_activityIndicatorView];
}

#pragma mark - UIscrollViewDelegate zoom

-(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale{
    _currentScale = scale;
    NSLog(@"current scale:%f",scale);
}
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
    return _imgView;
}
-(void)scrollViewDidZoom:(UIScrollView *)scrollView{
    //当捏或移动时,需要对center重新定义以达到正确显示未知
    CGFloat xcenter = scrollView.center.x,ycenter = scrollView.center.y;
    NSLog(@"adjust position,x:%f,y:%f",xcenter,ycenter);
    xcenter = scrollView.contentSize.width > scrollView.frame.size.width?scrollView.contentSize.width/2 :xcenter;
    ycenter = scrollView.contentSize.height > scrollView.frame.size.height ?scrollView.contentSize.height/2 : ycenter;
    //双击放大时,图片不能越界,否则会出现空白。因此需要对边界值进行限制。
    if(_isDoubleTapingForZoom){  
        NSLog(@"taping center");
        xcenter = kMaxZoom*(kScreenWidth - _touchX);
        ycenter = kMaxZoom*(kScreenHeight - _touchY);
        if(xcenter > (kMaxZoom - 0.5)*kScreenWidth){//放大后左边超界
            xcenter = (kMaxZoom - 0.5)*kScreenWidth;
        }else if(xcenter <0.5*kScreenWidth){//放大后右边超界
            xcenter = 0.5*kScreenWidth;
        }
        if(ycenter > (kMaxZoom - 0.5)*kScreenHeight){//放大后左边超界
            ycenter = (kMaxZoom - 0.5)*kScreenHeight +_offsetY*kMaxZoom;
        }else if(ycenter <0.5*kScreenHeight){//放大后右边超界
            ycenter = 0.5*kScreenHeight +_offsetY*kMaxZoom;
        }
        NSLog(@"adjust postion sucess, x:%f,y:%f",xcenter,ycenter);        
    }
    [_imgView setCenter:CGPointMake(xcenter, ycenter)];
}
#pragma mark - tap
-(void)tapImgViewHandle{
    NSLog(@"%d",_isTwiceTaping);
    if(_isTwiceTaping){
        return;
    }
    NSLog(@"tap once");
    
    [UIView animateWithDuration:0.6
        delay:0.0
        options: UIViewAnimationCurveEaseOut
        animations:^{
            _imgView.frame = CGRectMake(_scrollView.contentOffset.x+100, _scrollView.contentOffset.y+230, 10, 10);  
            self.alpha = 0.0;
        } 
        completion:^(BOOL finished){
            [self removeFromSuperview];
        }
    ];    
    
}
-(IBAction)tapImgViewHandleTwice:(UIGestureRecognizer *)sender{
    _touchX = [sender locationInView:sender.view].x;
    _touchY = [sender locationInView:sender.view].y;
    if(_isTwiceTaping){
        return;
    }
    _isTwiceTaping = YES;
    
    NSLog(@"tap twice");
    
    if(_currentScale > 1.0){
        _currentScale = 1.0;
        [_scrollView setZoomScale:1.0 animated:YES];
    }else{
        _isDoubleTapingForZoom = YES;
        _currentScale = kMaxZoom;
        [_scrollView setZoomScale:kMaxZoom animated:YES];
    }
    _isDoubleTapingForZoom = NO;
    //延时做标记判断,使用户点击3次时的单击效果不生效。
    [self performSelector:@selector(twiceTaping) withObject:nil afterDelay:0.65];
    NSLog(@"sdfdf");
}
-(void)twiceTaping{
    NSLog(@"no");
    _isTwiceTaping = NO;
}
-(void) saveTapHandler{
    if([_activityIndicatorView isAnimating]){
        return;
    }
    [_activityIndicatorView startAnimating] ;
    UIImageWriteToSavedPhotosAlbum(_imgView.image, self, @selector(imageSavedToPhotosAlbum: didFinishSavingWithError: contextInfo:), nil);
}
#pragma mark - savePhotoAlbumDelegate
- (void)imageSavedToPhotosAlbum:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *) contextInfo {  
    NSString *message;  
    NSString *title;  
    
    [_activityIndicatorView stopAnimating];
    if (!error) {
        title = @"恭喜";  
        message = @"成功保存到相册";  
    } else {  
        title = @"失败";  
        message = [error description];  
    }  
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil]; 
    [alert show];
}

@end
posted @ 2012-07-20 22:58  Gukw  阅读(19465)  评论(2编辑  收藏  举报