CZImagePreviewer 1.2.1

CZImagePreviewer 1.2.1

czeludzki 维护。



 
依赖于
SnapKit>= 0
Kingfisher>= 0
 

  • 作者
  • czeludzki

CZImagePreviewer

CI Status Version License Platform

示例

要运行示例项目,首先克隆仓库,然后从 Example 目录运行 pod install

特性

Kingfisher 图像加载和缓存基础
支持大图(测试了 1 亿像素图像),稳定内存消耗
支持 Gif
通过双击和捏合手势缩放
可自定义显示和消失动画
支持屏幕旋转
可自定义每个单元格的附件视图覆盖
可自定义持续覆盖的附件视图
可根据您提供的自定义视频视图

视图结构

  • 控制器.视图
    • CollectionView
      • ImageCell
        • Cell.ContentView
          • 用于图片缩放的ScrollView
            • UIImageView
          • 用于图片缩放的ScrollView(仅在显示大图时出现)
            • 平铺的ImageView
          • 辅助视图(由您提供)
      • 视频单元
        • Cell.ContentView
          • 视频视图(由您提供)
          • 辅助视图(由您提供)
    • 自定义控制台(默认在Controller.view之前,在CollectionView之上)

性能

在旧设备上浏览所有资源时的内存消耗(iPhone6s,iOS13,80%电池寿命)

  • 演示中包含超过一张1亿像素的图片
  • 在旧设备上运行(iPhone6s,iOS13,80%电池寿命)
    Performance

屏幕录制

大图显示
巨图显示
缩放
放大缩小
拖动以取消显示
滑动dismiss
屏幕旋转
旋转
视频播放
视频播放

用法

主要类

class Previewer: UIViewController { ... }

主要参数

public weak var delegate: Delegate?
public weak var dataSource: DataSource?

为展示而关闭

/// - Parameters:
///   - container: Tell Previewer which view component tirggers this display operation, all is for the display animation.
///   if nil, Previewer will provide a fade animate.
///   - fromSource: When displaying animate play, Previewer should known who is the animation acort.
///   Of course you can passing nil, then Previewer will get that from 'dataSource' by 'currentIndex'.
///   - index: Tell Previewer which resource you wanna show from the 'dataSource' at index
///   - controller: The controller which is presenting Previewer
public func display(fromImageContainer container: UIView? = nil, fromSource source: UIImage? = nil, presentingController: UIViewController? = nil, current index: Int = 0)

资源提供者:可以是 dataSources 数组的一员。

/// The base resource provider of ImageProvider and VideoProvider
public protocol ResourceProvider {}

ImageProvider

public protocol ImageProvider: ResourceProvider, Kingfisher.ImageDataProvider {}

视频提供者

public protocol VideoProvider: ResourceProvider, AnyObject {
    
    /// Video Content View
    var videoView: CZImagePreviewer.VideoView? { get }
        
    // Previewer should lintening the video size's changing, returning the new size in this closure
    typealias VideoSizeProvider = (_ videoSize: CGSize) -> Void
    var videoSizeProvider: VideoSizeProvider? { get set }
    
    func play()
    func pause()
    
    func cellDidEndDisplay()
    
    // You can do some preparing opreation for the video resource right here
    func perload()
}

数据源

public protocol DataSource: AnyObject {
    
    func numberOfItems(in previewer: Previewer) -> Int
    
    func imagePreviewer(_ previewer: Previewer, resourceForItemAtIndex index: Int) -> ResourceProvider?
    
    func imagePreviewer(_ previewer: Previewer, imageLoadingStateDidChanged state: Previewer.ImageLoadingState, at index: Int, accessoryView: AccessoryView?)
    
    /// Provide the accessory view for Previewer, this accessory view is not a part of scrolling or zooming effect. 
    /// Will calling when the index changed.
    /// - imagePreviewer: Previewer
    /// - index: which index of item need accessory view
    func imagePreviewer(_ imagePreviewer: Previewer, consoleForItemAtIndex index: Int) -> AccessoryView?
    
    /// Provider the accessory view for Previewer on each cell item. this is not part of zooming effect, but scrolling is.
    /// This accessory view will cover on the cell.
    /// Will calling when the index changed.
    /// - imagePreviewer: Previewer
    /// - cell: which cell adding this AccessoryView as the subview.
    /// - index: which index of item need accessory view
    func imagePreviewer(_ imagePreviewer: Previewer, accessoryViewForCell cell: CollectionViewCell, at index: Int) -> AccessoryView?
    
}

预览器代理

public protocol Delegate: AnyObject {
    
    func imagePreviewer(_ previewer: Previewer, willDisplayAtIndex index: Int)
    
    func imagePreviewer(_ previewer: Previewer, didDisplayAtIndex index: Int)
    
    func imagePreviewer(_ previewer: Previewer, indexDidChangedTo newIndex: Int, fromOldIndex oldIndex: Int)
    
    func imagePreviewer(_ previewer: Previewer, willDismissWithCell cell: CollectionViewCell, at index: Int) -> UIView?
    
    func imagePreviewerDidDismiss(_ previewer: Previewer)

    /// longPress gesture event happened with Previewer
    func imagePreviewer(_ previewer: Previewer, didLongPressAtIndex index: Int)
    
    /// By default, Previewer did add two kinds of gesture for dismiss: UITapGesture and UIPanningGesture.
    /// Call when Tap or Panning gesture been trigger. The returning Boolean value is deciding this dismiss should be happen or not.
    func imagePreviewer(_ previewer: Previewer, shouldDismissWithGesture gesture: UIGestureRecognizer, at index: Int) -> Bool
    
    /// Call after Previewer executed method: `deleteItems(at indexs: [Int])`
    func imagePreviewer(_ previewer: Previewer, didFinishDeletedItems indexs: [Int])   
}

更多用法可在演示中查看。

欢迎提出任何类型的问题。

需求

iOS 12+

依赖

SnapKit
Kingfisher

安装

CZImagePreviewer可通过CocoaPods获得。要安装它,只需将以下行添加到您的Podfile中

pod 'CZImagePreviewer'

作者

czeludzki,[email protected]

许可协议

CZImagePreviewer遵循MIT许可协议。有关更多信息,请参阅LICENSE文件。