Files
yuyin_ios/SweetParty/第三方库/KNPhotoBrowser/KNPhotoBrowserImageView.m
2025-08-08 11:05:33 +08:00

264 lines
9.1 KiB
Objective-C
Executable File

//
// KNPhotoBrowserImageView.m
// KNPhotoBrowser
//
// Created by LuKane on 16/8/17.
// Copyright © 2016年 LuKane. All rights reserved.
//
#import "KNPhotoBrowserImageView.h"
#import <SDWebImage/UIImageView+WebCache.h>
#import <SDWebImage/SDImageCache.h>
#import "KNProgressHUD.h"
#import "KNPhotoBrowserPch.h"
#import "KNPhotoBrowser.h"
#import "KNReachability.h"
@interface KNPhotoBrowserImageView()<UIScrollViewDelegate>{
NSURL *_url;
UIImage *_placeHolder;
}
@end
@implementation KNPhotoBrowserImageView
- (SDAnimatedImageView *)imageView{
if (!_imageView) {
_imageView = [[SDAnimatedImageView alloc] init];
[_imageView setUserInteractionEnabled:true];
[_imageView setFrame:CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height)];
_imageView.layer.cornerRadius = 0.1;
_imageView.clipsToBounds = true;
}
return _imageView;
}
- (UIScrollView *)scrollView{
if (!_scrollView) {
_scrollView = [[UIScrollView alloc] init];
[_scrollView setFrame:CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height)];
[_scrollView addSubview:self.imageView];
[_scrollView setDelegate:self];
[_scrollView setClipsToBounds:true];
}
return _scrollView;
}
- (instancetype)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
[self addSubview:self.scrollView];
[self initDefaultData];
if (@available(iOS 11.0, *)){
_scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
}
return self;
}
- (void)initDefaultData{
// 1.tap && doubleTap && longpress
UITapGestureRecognizer *tap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(scrollViewDidTap)];
UITapGestureRecognizer *doubleTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(scrollViewDidDoubleTap:)];
UILongPressGestureRecognizer *longPress =
[[UILongPressGestureRecognizer alloc] initWithTarget:self
action:@selector(longPressDidPress:)];
// 2.set gesture require
[tap setNumberOfTapsRequired:1];
[tap setNumberOfTouchesRequired:1];
[doubleTap setNumberOfTapsRequired:2];
[doubleTap setNumberOfTouchesRequired:1];
// 3.conflict resolution
[tap requireGestureRecognizerToFail:doubleTap];
// 4.add gesture
[self addGestureRecognizer:tap];
[self addGestureRecognizer:doubleTap];
[self addGestureRecognizer:longPress];
}
#pragma mark - 单击
- (void)scrollViewDidTap{
if(_singleTap){
_singleTap();
}
}
#pragma mark - 长按
- (void)longPressDidPress:(UILongPressGestureRecognizer *)longPress{
if(longPress.state == UIGestureRecognizerStateBegan){
if(_longPressTap){
_longPressTap();
}
}
}
#pragma mark - 双击
- (void)scrollViewDidDoubleTap:(UITapGestureRecognizer *)doubleTap{
// if image is download, if not ,just return;
if(!_imageView.image) return;
if(_scrollView.zoomScale <= 1){
// 1.catch the postion of the gesture
// 2.contentOffset.x of scrollView + location x of gesture
CGFloat x = [doubleTap locationInView:self].x + _scrollView.contentOffset.x;
// 3.contentOffset.y + location y of gesture
CGFloat y = [doubleTap locationInView:self].y + _scrollView.contentOffset.y;
[_scrollView zoomToRect:(CGRect){{x,y},CGSizeZero} animated:true];
}else{
// set scrollView zoom to original
[_scrollView setZoomScale:1.f animated:true];
}
}
- (void)imageWithUrl:(NSURL *)url
progressHUD:(KNProgressHUD *)progressHUD
placeHolder:(UIImage *)placeHolder
photoItem:(KNPhotoItems *)photoItem{
[progressHUD setHidden:true];
_url = url;
_placeHolder = placeHolder;
if(!url){
if (photoItem.isLocateGif == true) {
[_imageView setImage:photoItem.sourceImage];
}else {
[_imageView setImage:placeHolder];
}
[self layoutSubviews];
return;
}
if (![[KNReachability reachabilityForInternetConnection] isReachable]) { // no network
[progressHUD setHidden:true];
}else {
[progressHUD setHidden:false];
}
__weak typeof(self) weakSelf = self;
UIImage *image = [[SDImageCache sharedImageCache] imageFromCacheForKey:[url absoluteString]];
if(image){
[progressHUD setHidden:true];
}
// SDWebImage download image
[_imageView sd_setImageWithURL:url placeholderImage:placeHolder options:SDWebImageRetryFailed progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
CGFloat progress = ((CGFloat)receivedSize / expectedSize);
dispatch_async(dispatch_get_main_queue(), ^{
if(progressHUD){
progressHUD.progress = progress;
}
});
} completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
[self->_scrollView setZoomScale:1.f animated:true];
if(!error){
[progressHUD setProgress:1.f];
[weakSelf layoutSubviews];
}else{
[progressHUD setHidden:true];
}
}];
[self layoutSubviews];
}
- (void)layoutSubviews{
[super layoutSubviews];
_scrollView.frame = CGRectMake(10, 0, self.bounds.size.width - 20, self.bounds.size.height);
[self reloadFrames];
}
- (void)reloadFrames{
CGRect frame = _scrollView.frame;
if(_imageView.image){
CGSize imageSize = _imageView.image.size;
CGRect imageFrame = CGRectMake(0, 0, imageSize.width, imageSize.height);
// if scrollView.width <= height : that means Screen is not landscap
if (frame.size.width <= frame.size.height) {
// let width of the image set as width of scrollView, height become radio
CGFloat ratio = frame.size.width / imageFrame.size.width;
imageFrame.size.height = imageFrame.size.height * ratio;
imageFrame.size.width = frame.size.width;
}else{
if (frame.size.width / frame.size.height <= imageSize.width / imageSize.height) {
imageFrame.size.width = frame.size.width;
imageFrame.size.height = (frame.size.width / imageSize.width) * imageSize.height;
}else {
// let width of the image set as width of scrollView, height become radio
CGFloat ratio = frame.size.height / imageFrame.size.height;
imageFrame.size.width = imageFrame.size.width * ratio;
imageFrame.size.height = frame.size.height;
}
}
[_imageView setFrame:(CGRect){CGPointZero,imageFrame.size}];
// set scrollView contentsize
_scrollView.contentSize = _imageView.frame.size;
// set scrollView.contentsize as image.size , and get center of the image
_imageView.center = [self centerOfScrollViewContent:_scrollView];
// get the radio of scrollView.height and image.height
CGFloat maxScale = frame.size.height / imageFrame.size.height;
// get radio of the width
CGFloat widthRadit = frame.size.width / imageFrame.size.width;
// get the max radio
maxScale = widthRadit > maxScale?widthRadit:maxScale;
// if the max radio >= PhotoBrowerImageMaxScale, get max radio , else PhotoBrowerImageMaxScale
maxScale = maxScale > 2 ? maxScale:2;
// set max and min radio of scrollView
_scrollView.minimumZoomScale = 1;
_scrollView.maximumZoomScale = maxScale;
// set scrollView zoom original
_scrollView.zoomScale = 1.0f;
}else{
frame.origin = CGPointZero;
_imageView.frame = frame;
_scrollView.contentSize = _imageView.bounds.size;
}
_scrollView.contentOffset = CGPointZero;
}
- (CGPoint)centerOfScrollViewContent:(UIScrollView *)scrollView{
// scrollView.bounds.size.width > scrollView.contentSize.width :that means scrollView.size > image.size
CGFloat offsetX = (scrollView.bounds.size.width > scrollView.contentSize.width)?
(scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5 : 0.0;
CGFloat offsetY = (scrollView.bounds.size.height > scrollView.contentSize.height)?
(scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5 : 0.0;
CGPoint actualCenter = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX,
scrollView.contentSize.height * 0.5 + offsetY);
return actualCenter;
}
#pragma mark UIScrollViewDelegate
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
// zoom the subviews of the scrollView
return self.imageView;
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView{
// reset the center of image when dragging everytime
_imageView.center = [self centerOfScrollViewContent:scrollView];
}
@end