博客> 图片浏览器的实现原理
图片浏览器的实现原理
2017-08-18 16:51 评论:1 阅读:910 恋鱼乖

由于项目需求,最近做了一个仿新浪微博的图片浏览器功能,下面拿出来和大家做一个分享。

功能介绍

该图片浏览器的主要功能为从一组图片中点击一张图片时以动画的形式放大图片,生成图片浏览器实现左右滑动显示该组图片并实现缩放,当再次点击图片时则使图片浏览器消失。界面展示如下:

功能实现

首先在原始图片的展示时我们会为每一个UIImageView添加一个点击事件,该点击事件响应需要创建一个图片浏览器的实例对象,同时记录这些图片在所在的UIImageView信息,以便于图片在原始位置与图片浏览器之间的位置转换,随后调用图片浏览器的show方法展示所选图片。 方法如下:

// 设置图片浏览器显示的所有图片
NSMutableArray *photos = [NSMutableArray array];
int count = self.pic_urls.count;
for (int i = 0; i<count xss=removed xss=removed xss=removed>
其作用为将像素point由point所在视图转换到目标视图view中,返回在目标视图view中的像素值。

2.- (CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view;
<br> 
其作用为将像素point从view中转换到当前视图中,返回在当前视图中的像素值。

 3.- (CGRect)convertRect:(CGRect)rect fromView:(UIView *)view;
 <br> 
其作用为将rect从view中转换到当前视图中,返回在当前视图中的rect。
<br> 
<br> 
   
有兴趣的小伙伴可以在代码中尝试一下它们的区别。在得到转换过后的frame之后即可使用动画让其从当前位置大小调整到预定的效果。具体代码如下:
if (_photo.firstShow) { // 第一次显示的图片
    _photo.firstShow = NO; // 已经显示过了
    _imageView.frame = [_photo.srcImageView convertRect:_photo.srcImageView.bounds toView:nil];
    [UIView animateWithDuration:.3 animations:^{
        _imageView.frame = imageFrame;
    }];
}else{
    _imageView.frame = imageFrame;
}
####关键点2:图片浏览器中UIImageView的重用
在不使用重用机制时就会一次性将大量的UIImageView加入到UIScrollView中,这样就会内存的急剧消耗,当图片数量过多时还有可能引起程序崩溃,并且有的加载过的图片并不会马上显示到界面上,考虑到这一点我们便可自行实现重用机制。该机制的实现主要依赖于UIScrollViewDelegate的- (void)scrollViewDidScroll:(UIScrollView *)scrollView;首先要根据UIScrollView的偏移量来判断哪些图片已经超出了手机屏幕的显示区域,把超出显示区域的图片所在的UIImageView加入到复用池后将其从UIScrollView中移除,为了使复用池中的可用视图只有两个,还要在最后做一个判断当复用池中可用视图超过两个后就将任意一个删除。具体实现代码如下:

// 回收不再显示的ImageView //注:kPhotoViewIndex()为一个宏定义,用于根据所传入的视图来计算该视图显示的为第几张图片 for (YLPhotoView *photoView in _visiblePhotoViews) { photoViewIndex = kPhotoViewIndex(photoView); if (photoViewIndex < firstIndex> lastIndex) { photoView.zoomScale = 1.0; [_reusablePhotoViews addObject:photoView]; [photoView removeFromSuperview]; } } while (_reusablePhotoViews.count > 2) { [_reusablePhotoViews removeObject:[_reusablePhotoViews anyObject]]; }

在实现对复用池的操作后即可对将要显示的图片进行操作,首先还是要根据偏移量判断当前区域应该显示的图片,之后为这些图片提供UIImageView,提供的方式分为两种,第一种为复用池中存在可用的UIImageView,第二种即复用池中不存在可用的UIImageView。复用池为一个NSSet容器,当复用池可用时就从复用池中获得视图,并将该视图从复用池中移除,当复用池不存在时则需要创建视图,当图片从界面消失时再将该视图添加到复用池中,这样在整个图片浏览器的使用当中我们只需创建两个UIImageView即可。实现代码如下:

pragma mark 显示一个图片view

YLPhotoView *photoView = [self dequeueReusablePhotoView]; if (!photoView) { // 添加新的图片view photoView = [[YLPhotoView alloc] init]; photoView.photoViewDelegate = self; } [_photoScrollView addSubview:photoView];

####关键点3:图片浏览器中图片缩放时使图片居中显示
图片缩放的功能是基于UIScrollView来实现的,基本的方法就是实现UIScrollViewDelegate的- (nullable UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView方法,但是当我们在对图片进行缩放时却无法使图片居中显示,这就需要我们用代码手动处理。解决这个问题我们只需在UIScrollViewDelegate的- (void)scrollViewDidZoom:(UIScrollView *)scrollView方法中根据缩放后图片的大小来确定UIImageView的Center属性,具体实现如下:
  • (void)scrollViewDidZoom:(UIScrollView )scrollView { 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; _imageView.center = CGPointMake(scrollView.contentSize.width 0.5 + offsetX,scrollView.contentSize.height * 0.5 + offsetY); }
    
    这样就基本实现了图片浏览器的基本功能。
    ###总结
    该图片浏览器的主要特点就是尽可能的减少图片对内存空间的占用,并能使所查看的图片与图片浏览器中的图片能够进行流畅、自然的切换。为了更加具有说服力我将没有重用之前和重用优化之后的内存占用截图附上:
    ![ Enter your image description here: ](/Users/yuu/Desktop/技术博客/1.pic.jpg)
    ![ Enter your image description here: ](/Users/yuu/Desktop/技术博客/2.pic.jpg)
    当然该图片浏览器仍然存在不足,比如在点击原始图片时异步获取与之相对应网络图片进行显示的功能还没能完善,在今后我也会尝试完善这一功能。
收藏
2
sina weixin mail 回到顶部