当前位置: 移动技术网 > 移动技术>移动开发>IOS > iOS- XKZoomingView 简单的图片预览,支持横屏【手势:单击、双击、放大缩小】

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

2018年11月28日  | 移动技术网移动技术  | 我要评论

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

 

如对本文有疑问, 点击进行留言回复!!

相关文章:

  • unity打包脚本

    require("utils") -- platform android ios -- switch publi... [阅读全文]
  • iOS实现图片轮播器

    iOS实现图片轮播器

    有时候肯能会用到图片轮播器,做广告的效果。下面详细介绍ios如何实现图片轮播器1.新建一个项目,导入5张图片(为了代码方便,我把图片命名规范了,其实无所谓)2.... [阅读全文]
  • ios实现简易队列

    本文实例为大家分享了ios实现简易队列的具体代码,供大家参考,具体内容如下满足一些特殊需求接口部分(队列支持需求)#import <foundation/... [阅读全文]
  • iOS实现简易钟表

    本文实例为大家分享了ios实现简易钟表的具体代码,供大家参考,具体内容如下效果图:注意:表盘是一个uiimageview控件,设置image为表盘图片核心代码:... [阅读全文]
  • iOS实现列表折叠效果

    本文实例为大家分享了ios实现列表折叠效果的具体代码,供大家参考,具体内容如下实现列表折叠效果其实比较简单,点击列表头部的时候,把返回列表行数设为 0,就是收起... [阅读全文]
  • iOS实现3D卡片式轮播效果

    本文实例为大家分享了ios实现3d卡片式轮播效果的具体代码,供大家参考,具体内容如下效果:参考uitableview的uitableviewdatasource... [阅读全文]
  • iOS实现卡片式滚动效果 iOS实现电影选片效果

    本文实例为大家分享了ios实现卡片式滚动效果的具体代码,供大家参考,具体内容如下先来张效果图吧:直接上源码了:cardscrollview.h#import &... [阅读全文]
  • iOS自定义View实现卡片滑动

    本文实例为大家分享了ios自定义view实现卡片滑动效果的具体代码,供大家参考,具体内容如下说明控件基于uiview封装完成,采用uipangesturerec... [阅读全文]
  • iOS实现简单抽屉效果

    抽屉效果所谓抽屉效果就是三个视图,向右拖拽显示左边的视图,向左拖拽显示右边的视图,当拖拽大于屏幕的一半时最上面的视图会自动定位到一边,当点击左边或右边视图时会最... [阅读全文]
验证码:
移动技术网