• iOS- XKZoomingView 简单的图片缩放预览,支持横屏、长图【手势:单击、双击、放大缩小】


    XKZoomingView.h

    #import <UIKit/UIKit.h>
    
    @interface XKZoomingView : UIScrollView
    /**
     本地图片
     */
    @property (nonatomic, strong) UIImage *mainImage;
    
    /**
     图片显示
     */
    @property (nonatomic, strong) UIImageView *mainImageView;
    @end

    XKZoomingView.m

    #import "XKZoomingView.h"
    @interface XKZoomingView()<UIScrollViewDelegate>
    /**
     当前图片偏移量
     */
    @property (nonatomic,assign) CGPoint currPont;
    @end
    @implementation XKZoomingView
    
    - (instancetype)init{
        self = [super init];
        if (self) {
            [self setup];
        }
        return self;
    }
    - (instancetype)initWithFrame:(CGRect)frame{
        self = [super initWithFrame:frame];
        if (self) {
            [self setup];
        }
        return self;
    }
    - (void)setup{
        self.backgroundColor = [[UIColor grayColor]colorWithAlphaComponent:0.2];
        self.delegate = self;
        self.showsHorizontalScrollIndicator = NO;
        self.showsVerticalScrollIndicator = NO;
        self.decelerationRate = UIScrollViewDecelerationRateFast;
        self.maximumZoomScale = 3;
        self.minimumZoomScale = 1;
        self.alwaysBounceHorizontal = NO;
        self.alwaysBounceVertical = NO;
        self.layer.masksToBounds = YES;
        if (@available(iOS 11.0, *)) {
            self.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
        }
        [self addSubview:self.mainImageView];
    
        _currPont = CGPointZero;
    
        ///监听屏幕旋转
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarOrientationChange:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
        ///单击
        UITapGestureRecognizer *tapSingle = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapSingleSponse:)];
        //设置手势属性
        tapSingle.numberOfTapsRequired = 1;
        tapSingle.delaysTouchesEnded = NO;
        [self.mainImageView addGestureRecognizer:tapSingle];
        ///双击
        UITapGestureRecognizer *tapDouble = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapDoubleSponse:)];
        //设置手势属性
        tapDouble.numberOfTapsRequired = 2;
        [self.mainImageView addGestureRecognizer:tapDouble];
        ///避免手势冲突
        [tapSingle requireGestureRecognizerToFail:tapDouble];
    }
    
    #pragma mark - layoutSubviews
    - (void)layoutSubviews{
        [super layoutSubviews];
        ///放大或缩小中
        if (self.zooming || self.zoomScale != 1.0 || self.zoomBouncing) {
            return;
        }
        
        ///设置图片尺寸
        if (_mainImage) {
            CGRect imgRect = [self getImageViewFrame];
            self.mainImageView.frame = imgRect;
            ///设置content size
            if (CGRectGetHeight(imgRect) > CGRectGetHeight(self.frame)) {
                [self setContentSize:CGSizeMake(CGRectGetWidth(self.frame), CGRectGetHeight(imgRect))];
            }
            else{
                [self setContentSize:CGSizeMake(CGRectGetWidth(self.frame), CGRectGetHeight(self.frame))];
            }
        }
        
    }
    - (void)setMainImage:(UIImage *)mainImage{
        _mainImage = mainImage;
        self.mainImageView.image = _mainImage;
        [self setContentOffset:CGPointMake(0, 0)];
        [self setNeedsLayout];
    }
    
    /**
     根据图片原始大小,获取图片显示大小
     @return CGRect
     */
    - (CGRect)getImageViewFrame{
        if (_mainImage) {
            CGRect imageRect;
            CGFloat scWidth = self.frame.size.width;
            CGFloat scHeight = self.frame.size.height;
            ///width
            if (_mainImage.size.width > scWidth) {
                imageRect.size.width = scWidth;
                CGFloat ratioHW = _mainImage.size.height/_mainImage.size.width;
                imageRect.size.height = ratioHW * imageRect.size.width;
                imageRect.origin.x = 0;
            }
            else{
                imageRect.size.width = _mainImage.size.width;
                imageRect.size.height = _mainImage.size.height;
                imageRect.origin.x = (scWidth - imageRect.size.width)/2;
            }
            ///height
            if (imageRect.size.height > scHeight) {
                
                imageRect.origin.y = 0;
            }
            else{
                imageRect.origin.y = (scHeight - imageRect.size.height)/2;
            }
            return imageRect;
        }
        return CGRectZero;
    }
    /**
     获取点击位置后所需的偏移量【目的是呈现点击位置在试图上】
     
     @param location 点击位置
     */
    - (void)zoomingOffset:(CGPoint)location{
        CGFloat lo_x = location.x * self.zoomScale;
        CGFloat lo_y = location.y * self.zoomScale;
        
        CGFloat off_x;
        CGFloat off_y;
        ///off_x
        if (lo_x < CGRectGetWidth(self.frame)/2) {
            off_x = 0;
        }
        else if (lo_x > self.contentSize.width - CGRectGetWidth(self.frame)/2){
            off_x = self.contentSize.width - CGRectGetWidth(self.frame);
        }
        else{
            off_x = lo_x - CGRectGetWidth(self.frame)/2;
        }
        
        ///off_y
        if (lo_y < CGRectGetHeight(self.frame)/2) {
            off_y = 0;
        }
        else if (lo_y > self.contentSize.height - CGRectGetHeight(self.frame)/2){
            if (self.contentSize.height <= CGRectGetHeight(self.frame)) {
                off_y = 0;
            }
            else{
                off_y = self.contentSize.height - CGRectGetHeight(self.frame);
            }
            
        }
        else{
            off_y = lo_y - CGRectGetHeight(self.frame)/2;
        }
        [self setContentOffset:CGPointMake(off_x, off_y)];
    }
    
    #pragma mark - 重置图片
    - (void)resetImageViewState{
        self.zoomScale = 1;
        _mainImage = nil;;
        self.mainImageView.image = nil;
       
    }
    #pragma mark - 变量
    - (UIImageView *)mainImageView {
        if (!_mainImageView) {
            _mainImageView = [UIImageView new];
            _mainImageView.image = nil;
            _mainImageView.contentMode = UIViewContentModeScaleAspectFit;
            _mainImageView.userInteractionEnabled = YES;
        }
        return _mainImageView;
    }
    
    
    #pragma mark - 单击
    - (void)tapSingleSponse:(UITapGestureRecognizer *)singleTap{
        if (!self.mainImageView.image) {
            return;
        }
        
        if (self.zoomScale != 1) {
            [UIView animateWithDuration:0.2 animations:^{
                self.zoomScale = 1;
            } completion:^(BOOL finished) {
                [self setContentOffset:_currPont animated:YES];
            }];
        }
    }
    #pragma mark - 双击
    - (void)tapDoubleSponse:(UITapGestureRecognizer *)doubleTap{
        if (!self.mainImageView.image) {
            return;
        }
        CGPoint point = [doubleTap locationInView:self.mainImageView];
        if (self.zoomScale == 1) {
            [UIView animateWithDuration:0.2 animations:^{
                self.zoomScale = 2.0;
                [self zoomingOffset:point];
            }];
        }
        else{
            [UIView animateWithDuration:0.2 animations:^{
                self.zoomScale = 1;
            } completion:^(BOOL finished) {
                [self setContentOffset:_currPont animated:YES];
            }];
        }
    }
    
    
    #pragma mark - UIScrollViewDelegate
    - (void)scrollViewDidZoom:(UIScrollView *)scrollView {
        if (!self.mainImageView.image) {
            return;
        }
        CGRect imageViewFrame = self.mainImageView.frame;
        CGFloat width = imageViewFrame.size.width,
        height = imageViewFrame.size.height,
        sHeight = scrollView.bounds.size.height,
        sWidth = scrollView.bounds.size.width;
        if (height > sHeight) {
            imageViewFrame.origin.y = 0;
        } else {
            imageViewFrame.origin.y = (sHeight - height) / 2.0;
        }
        if (width > sWidth) {
            imageViewFrame.origin.x = 0;
        } else {
            imageViewFrame.origin.x = (sWidth - width) / 2.0;
        }
        self.mainImageView.frame = imageViewFrame;
    }
    
    - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
        return self.mainImageView;
    }
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView{
        if (self.isZooming || self.zoomScale != 1) {
            return;
        }
        _currPont = scrollView.contentOffset;
        
    }
    #pragma mark - 监听屏幕旋转通知
    - (void)statusBarOrientationChange:(NSNotification *)notification{
        self.zoomScale = 1;
    }
    - (void)dealloc{
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
    }
    
    @end

    USE

    XKZoomingView *zoomView = [[XKZoomingView alloc]init];
    zoomView.frame = self.view.bounds;
    zoomView.mainImage = [UIImage imageNamed:@""];
    [self.view addSubview:zoomView];

     ELSE

  • 相关阅读:
    C# 反射设置属性帮助类
    WPF xaml中写代码
    redis 击穿、穿透、雪崩产生原因及解决方案
    Linux环境安装Tengine
    lsof使用说明
    Delve调试器简单使用说明
    web访问日志分析
    MongoDB中文社区 Freetalk,一起来玩快闪!
    在线研讨会:实时数据同步应用场景及实现方案探讨
    labview使用百度地图API,报错getContext方法未定义
  • 原文地址:https://www.cnblogs.com/wangkejia/p/10025041.html
Copyright © 2020-2023  润新知