zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    leetcode 18 4Sum
    leetcode 71 Simplify Path
    leetcode 10 Regular Expression Matching
    leetcode 30 Substring with Concatenation of All Words
    leetcode 355 Design Twitte
    leetcode LRU Cache
    leetcode 3Sum
    leetcode Letter Combinations of a Phone Number
    leetcode Remove Nth Node From End of List
    leetcode Valid Parentheses
  • 原文地址:https://www.cnblogs.com/Gukw/p/2601800.html
Copyright © 2011-2022 走看看