一款视频图片浏览器SZPhotoVideoBrowser

闲暇时做的一个可以浏览图片以及视频的框架。效果图如下:


Untitled5.gif

基本功能

  • 视频和图片(含GIF)的混合浏览。
  • 支持屏幕旋转,横屏浏览。
  • 支持双击放大图片、拖曳退出浏览等多种手势操作。

说明:本项目是在GKPhotoBrowser基础上修改及扩展的,GKPhotoBrowser是一款支持图片浏览的图片浏览器,本项目新增了视频播放的功能,播放器修改自SBPlayer。此外,本项目保留了GKPhotoBrowser的原有功能。

如何使用

具体方法详见下载的demo。其他功能或样式可参考GKPhotoBrowser原项目的说明。

下载地址

https://github.com/imsz5460/SZPhotoVideoBrowser

核心代码

1、图片的复用机制:简单来说,会预先加载3张紧邻的图片,比如现在屏幕显示的是第2张图,则第1张与第3张也一并加载了,这3张图放在_visiblePhotoViews数组,这样用户左滑右滑都能有较好的体验。_visiblePhotoViews是随着显示图片的变化而更新的,当新的图片加进来,则有原图片从这个数组移除,并把移除的图片放到缓存池。这样下次加载图片时首先去缓存池中获取,如果没有才重新创建新图片。同时,如果需要展示的是视频,则在图片上直接加载视频view。具体可参看代码实现。

//在scrollview监听滚动的代理方法中设置图片
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (self.isRotation) return;
    [self updateReusableViews];
    [self setupPhotoViews];
}

- (void)updateReusableViews {
    NSMutableArray *viewsForRemove = [NSMutableArray new];
    for (GKPhotoView *photoView in _visiblePhotoViews) {
        if ((photoView.frame.origin.x + photoView.frame.size.width < self.photoScrollView.contentOffset.x - self.photoScrollView.frame.size.width) || (photoView.frame.origin.x > self.photoScrollView.contentOffset.x + 2 * self.photoScrollView.frame.size.width)) {
        
            [photoView._playerView stop];
           
            [photoView removeFromSuperview];
            GKPhoto *photo = nil;
            [photoView setupPhoto:photo];
            [viewsForRemove addObject:photoView];
            [_reusablePhotoViews addObject:photoView];
        }
    }
    [_visiblePhotoViews removeObjectsInArray:viewsForRemove];
}

- (void)setupPhotoViews {
    CGFloat index2 = self.photoScrollView.contentOffset.x / self.photoScrollView.frame.size.width;
    NSInteger index = index2 + 0.5;
    NSInteger i  = index2;
    for (NSInteger i = index - 1; i <= index + 1; i++) {
        if (i < 0 || i >= self.photos.count) {
            continue;
        }
        GKPhotoView *photoView = [self photoViewForIndex:i];
        if (photoView == nil) {
            photoView               = [self dequeueReusablePhotoView];
            CGRect frame            = self.photoScrollView.bounds;
            
            CGFloat photoScrollW    = frame.size.width;
            CGFloat photoScrollH    = frame.size.height;
            // 调整当前显示的photoView的frame
            CGFloat w = photoScrollW - kPhotoViewPadding * 2;
            CGFloat h = photoScrollH;
            CGFloat x = kPhotoViewPadding + i * (kPhotoViewPadding * 2 + w);
            CGFloat y = 0;

            photoView.frame = CGRectMake(x, y, w, h);
            photoView.tag   = i;
            [self.photoScrollView addSubview:photoView];
            
            GKPhoto *photo = self.photos[i];
            if (photo.isVideo) {
                [photoView addSubview: photoView.playerView];
                photoView.clipsToBounds = YES;//防止上次的横屏挡住旁边的view
            }
           
            [_visiblePhotoViews addObject:photoView];
            [photoView resetFrame];
        }
        if (photoView.photo == nil && self.isShow) {
            [photoView setupPhoto:self.photos[i]];
        }
    }
 
        if (index2 == i) {
            if (preindex != index2) {
                [_playerView pause];
                preindex = i;
                [self currentPlayViewPlay:i];
            }
        }

    // 更换photoView
    if (index != self.currentIndex && self.isShow && (index >= 0 && index < self.photos.count)) {
        self.currentIndex = index;
        
        GKPhotoView *photoView = [self currentPhotoView];
        if (photoView.scrollView.zoomScale > 1.0 ) {
            [self removePanGesture];
        }else {
            [self addPanGesture:NO];
        }
        [self updateLabel];
        
        if ([self.delegate respondsToSelector:@selector(photoBrowser:didChangedIndex:)]) {
            [self.delegate photoBrowser:self didChangedIndex:self.currentIndex];
        }
    }
}
// 重用页面
- (GKPhotoView *)dequeueReusablePhotoView {
    GKPhotoView *photoView = [self.reusablePhotoViews anyObject];
    if (photoView) {
       
        [photoView._playerView stop];
       
        [_reusablePhotoViews removeObject:photoView];
    }else {
        photoView = [[GKPhotoView alloc] initWithFrame:self.photoScrollView.bounds imageProtocol:_imageProtocol];
    }
    photoView.tag =  -1;
    return photoView;
}

你可能感兴趣的:(一款视频图片浏览器SZPhotoVideoBrowser)