图片浏览,手势放大缩小

功能:

第一页展示图片缩略图,用collectionView实现,保证长宽比;

点击图片变成横向图片浏览器,需要左右滑动切换图片,手势放大缩小,点击退出


原理分析:

第一页用collectionView展示图片,接口实现用户可选择列数

第二页滑动浏览图片底部是一个大的scrollView,里面横向设置若干个小的scrollView(需要用到scrollView的放大缩小功能)


实现步骤:

1.设置第一页缩略图展示

- (void)setupCollectionView{
    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init];
    layout.minimumInteritemSpacing = margin;
    layout.minimumLineSpacing = margin;
    self.collection = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight - 64) collectionViewLayout:layout];
    self.collection.backgroundColor = BGColor;
    self.collection.delegate = self;
    self.collection.dataSource = self;
    [self.view addSubview:self.collection];
    [self.collection registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:cellID];
}

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
    return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return self.photoArray.count;
}
//每一个分组的上左下右间距
-(UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
    return UIEdgeInsetsMake(margin, margin, margin, margin);
}
//定义每一个cell的大小
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{;
    return CGSizeMake(_itemWidth, _itemWidth);
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:cellID forIndexPath:indexPath];
    //UICollectionViewCell *cell= [collectionView cellForItemAtIndexPath:indexPath];
    cell.backgroundColor=[UIColor whiteColor];
    cell.layer.cornerRadius = 10;
    cell.clipsToBounds = YES;
    // 移除子视图,防止循环引用
    for (UIView *view in cell.contentView.subviews) {
        if (view) {
            [view removeFromSuperview];
        }
    }

    UIImageView *imageView = [[UIImageView alloc]initWithFrame:cell.bounds];
    UIImage *image = self.imageArray[indexPath.row];
    imageView.image = image;
    CGSize imageReSize = [self resizeImageSize:image.size];
    imageView.frame = CGRectMake((_itemWidth - imageReSize.width) / 2, (_itemWidth - imageReSize.height) / 2, imageReSize.width, imageReSize.height);
    [cell.contentView addSubview:imageView];
    return cell;
}

2.缩略图的实现需要判断图片大小,以适配item长宽,调整长宽比,这里封装了方法

-(CGSize)resizeImageSize:(CGSize)size{
    CGFloat width = size.width;
    CGFloat height = size.height;
    CGFloat maxHeight = _itemWidth;
    CGFloat maxWidth = _itemWidth;
    //如果图片尺寸大于view尺寸,按比例缩放
    if(width > maxWidth || height > width){
        CGFloat ratio = height / width;
        CGFloat maxRatio = maxHeight / maxWidth;
        if(ratio < maxRatio){
            width = maxWidth;
            height = width*ratio;
        }else{
            height = maxHeight;
            width = height / ratio;
        }
    }
    return CGSizeMake(width, height);
}

3.设置点击跳转代理方法,点击图片把图片数组和点击的index传个下一页,下一页显示在window视图上

//cell的点击事件
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
    RFPhotoScrollerView *scrollerView = [[RFPhotoScrollerView alloc]initWithImagesArray:self.imageArray currentIndex:indexPath.row];
    [[[UIApplication sharedApplication] keyWindow] addSubview:scrollerView];
}


设置图片显示页面RFPhotoScrollerView

4.初始化init方法,设置成员变量,添加手势和页码显示

- (instancetype)initWithImagesArray:(NSArray *)imagesArray currentIndex:(NSInteger)currentIndex{
    _imagesArray = [imagesArray copy];
    _currentIndex = currentIndex;
    _offset = 0.0;
    self = [super initWithFrame:[[UIScreen mainScreen]bounds]];
    if (self) {
        // 设置scrollView
        [self setupScrollView];
        // 添加点击手势
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapAction:)];
        [self addGestureRecognizer:tap];

        // 页码显示
        UILabel *pageLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, CGRectGetMaxY(self.frame) - 100, kScreenWidth, 50)];
        _pageLabel = pageLabel;
        pageLabel.textAlignment = NSTextAlignmentCenter;
        pageLabel.textColor = [UIColor whiteColor];
        pageLabel.font = [UIFont systemFontOfSize:18];
        pageLabel.text = [NSString stringWithFormat:@"%ld/%ld",_currentIndex+1,_imagesArray.count];
        [self addSubview:pageLabel];
    }
    return self;
}


5.设置大的scrollView,把小的scrollView加到上面,并设置小scrollView的放大缩小范围,图片也需要适配

- (void)setupScrollView{
    UIScrollView *scrollView = [[UIScrollView alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
    self.scrollView = scrollView;
    scrollView.delegate = self;
    scrollView.showsHorizontalScrollIndicator = NO;
    scrollView.showsVerticalScrollIndicator = NO;
    scrollView.pagingEnabled =  YES;
    scrollView.bounces = NO;
    scrollView.backgroundColor =[UIColor blackColor];
    scrollView.contentSize = CGSizeMake(_imagesArray.count * kScreenWidth, kScreenHeight);
    scrollView.contentOffset = CGPointMake(_currentIndex * kScreenWidth, 0);
    [self addSubview:scrollView];
    
    // 添加图片
    [_imagesArray enumerateObjectsUsingBlock:^(NSString *imageNamed, NSUInteger idx, BOOL * _Nonnull stop) {
        UIScrollView *itemScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(idx * kScreenWidth, 0, kScreenWidth, kScreenHeight)];
        self.itemScrollView = itemScrollView;
        itemScrollView.delegate = self;
        itemScrollView.maximumZoomScale = 3.0;//最大缩放倍数
        itemScrollView.minimumZoomScale = 1.0;//最小缩放倍数
        itemScrollView.showsVerticalScrollIndicator = NO;
        itemScrollView.showsHorizontalScrollIndicator = NO;
        itemScrollView.backgroundColor =[UIColor blackColor];
        [itemScrollView setZoomScale:1];
        [self.scrollView addSubview:itemScrollView];
        

        
        // 添加图片并适配
        UIImage *image = _imagesArray[idx];
        CGSize imageReSize = [self resizeImageSize:image.size];
        UIImageView *imageView = [[UIImageView alloc]init];
        [itemScrollView addSubview:imageView];
        imageView.image = image;
        imageView.userInteractionEnabled = YES;
        [imageView setContentMode:UIViewContentModeScaleAspectFit];
        imageView.frame = CGRectMake((kScreenWidth - imageReSize.width) / 2, (kScreenHeight - imageReSize.height) / 2, imageReSize.width, imageReSize.height);
    }];

}
// 调整图片
-(CGSize)resizeImageSize:(CGSize)size{
    CGFloat width = size.width;
    CGFloat height = size.height;
    CGFloat maxHeight = kScreenHeight;
    CGFloat maxWidth = kScreenWidth;
    //如果图片尺寸大于view尺寸,按比例缩放
    if(width > maxWidth || height > width){
        CGFloat ratio = height / width;
        CGFloat maxRatio = maxHeight / maxWidth;
        if(ratio < maxRatio){
            width = maxWidth;
            height = width*ratio;
        }else{
            height = maxHeight;
            width = height / ratio;
        }
    }
    return CGSizeMake(width, height);
}

6.设置放大缩小代理方法

#pragma mark UIScrollViewDelegate
//指定缩放view
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
    for (UIView *v in scrollView.subviews){
        return v;
    }
    return nil;
}

// 正在放大缩小
-(void)scrollViewDidZoom:(UIScrollView *)scrollView{
    // 增量为=位移距离/2
    UIView *v = [scrollView.subviews objectAtIndex:0];
    if ([v isKindOfClass:[UIImageView class]]){
        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;
        v.center = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX,
                               scrollView.contentSize.height * 0.5 + offsetY);
    }
    
    
}
// 滚动完成
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;{
    NSInteger page = scrollView.contentOffset.x / kScreenWidth;
    _currentIndex = page;
    _pageLabel.text = [NSString stringWithFormat:@"%ld/%ld",page+1,_imagesArray.count];
    if (scrollView == self.scrollView){
        CGFloat x = scrollView.contentOffset.x;
        if (x !=_offset){
            _offset = x;
            for (UIScrollView *s in scrollView.subviews){
                if ([s isKindOfClass:[UIScrollView class]]){
                    [s setZoomScale:1.0];
                }
            }
        }
    }
}


github只有浏览本地图片:https://github.com/RockyFung/RFPhotoBrowser


你可能感兴趣的:(iOS开发)