| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- //
- // ZoomableImageView.m
- // AIIM
- //
- // Created by qitewei on 2025/5/21.
- //
- #import "ZoomableImageView.h"
- @implementation ZoomableImageView
- - (instancetype)initWithFrame:(CGRect)frame {
- self = [super initWithFrame:frame];
- if (self) {
- [self setupView];
- }
- return self;
- }
- - (void)setupView {
- // 设置滚动视图属性
- self.delegate = self;
- self.showsVerticalScrollIndicator = NO;
- self.showsHorizontalScrollIndicator = NO;
- self.decelerationRate = UIScrollViewDecelerationRateFast;
-
- // 添加图片视图
- _imageView = [[UIImageView alloc] initWithFrame:self.bounds];
- _imageView.contentMode = UIViewContentModeScaleAspectFit;
- _imageView.userInteractionEnabled = YES;
- [self addSubview:_imageView];
-
- // 添加手势
- UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];
- doubleTap.numberOfTapsRequired = 2;
- [_imageView addGestureRecognizer:doubleTap];
- }
- - (void)setImage:(UIImage *)image {
- self.imageView.image = image;
- [self resetZoom];
- }
- - (void)resetZoom {
- [self layoutImageView];
- }
- - (void)layoutImageView {
- if (!self.imageView.image) return;
-
- CGSize imageSize = self.imageView.image.size;
- CGSize boundsSize = self.bounds.size;
-
- // 1. 计算使宽度匹配屏幕的缩放比例
- CGFloat widthScale = boundsSize.width / imageSize.width;
-
- // 2. 设置缩放范围
- self.minimumZoomScale = widthScale;
- self.maximumZoomScale = widthScale * 4.0;
- self.zoomScale = widthScale;
-
- // 3. 调整contentSize和imageView的frame
- [self updateContentSize];
- [self centerImageView];
- }
- - (void)updateContentSize {
- if (!self.imageView.image) return;
-
- CGSize imageSize = self.imageView.image.size;
- CGFloat scale = self.zoomScale;
-
- // 内容大小要基于缩放后的尺寸
- self.contentSize = CGSizeMake(imageSize.width * scale, imageSize.height * scale);
- self.imageView.frame = CGRectMake(0, 0, self.contentSize.width, self.contentSize.height);
- }
- - (void)centerImageView {
- CGSize boundsSize = self.bounds.size;
- CGSize contentSize = self.contentSize;
-
- // 计算水平和垂直偏移
- CGFloat horizontalInset = MAX(0, (boundsSize.width - contentSize.width) / 2);
- CGFloat verticalInset = MAX(0, (boundsSize.height - contentSize.height) / 2);
-
- // 设置contentInset保持居中
- self.contentInset = UIEdgeInsetsMake(verticalInset, horizontalInset, verticalInset, horizontalInset);
- }
- #pragma mark - UIScrollViewDelegate
- - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
- return self.imageView;
- }
- - (void)scrollViewDidZoom:(UIScrollView *)scrollView {
- [self centerImageView];
- }
- #pragma mark - Gesture Handlers
- - (void)handleDoubleTap:(UITapGestureRecognizer *)gesture {
- if (self.zoomScale > self.minimumZoomScale) {
- [self setZoomScale:self.minimumZoomScale animated:YES];
- } else {
- CGFloat newZoomScale = self.maximumZoomScale;
- CGPoint touchPoint = [gesture locationInView:self.imageView];
-
- CGFloat w = self.bounds.size.width / newZoomScale;
- CGFloat h = self.bounds.size.height / newZoomScale;
-
- [self zoomToRect:CGRectMake(touchPoint.x - w/2, touchPoint.y - h/2, w, h)
- animated:YES];
- }
- }
- - (void)handleSingleTap:(UITapGestureRecognizer *)gesture {
- // 通知控制器单击事件
- if ([self.superview respondsToSelector:@selector(handleSingleTap:)]) {
- [self.superview performSelector:@selector(handleSingleTap:) withObject:gesture];
- }
- }
- @end
|