AsyncImageView

Build Status Carthage compatible

这是一个 Swift 框架,提供了一个易于使用的 UIImageView 子类,可以有效地异步加载和渲染图像,并提供缓存和错误处理。

示例

要尝试使用它,您可以运行此仓库中包含的示例。 您需要在 ImageFetcher 中提供您自己的 Flickr API 密钥。

使用方法

假设您有一个包含要渲染图像的 struct

struct Image: Hashable {
    let url: URL
}

首先,您需要定义自己的 RendererType

struct ImageViews {
    typealias RendererType = AnyRenderer<Renderer.RenderData, ImageResult, NoError>
    typealias ImageView = AsyncImageView<Renderer.RenderData, Data, RendererType, RendererType>
 
    static func createView() -> ImageView {
        return ImageView(
            initialFrame: .zero,
            renderer: Renderer.singleton.renderer
        )
    }
      
    struct Data: ImageViewDataType {
        let image: Image
        
        init(image: Image) {
            self.image = image
        }
        
        func renderDataWithSize(_ size: CGSize) -> Renderer.RenderData {
            return RenderData(imageData: image, size: size)
        }
    }
    
    final class Renderer {
        let renderer: RendererType
        
        static let singleton: Renderer = {
            return Renderer()
        }()
        
        init() {
            self.renderer = AnyRenderer(
                RemoteImageRenderer<RemoteRenderData>()
                    // AsyncImageView ensures that errors are handled explicitly.
                    // See "fallbacks" below for an alternative to this.
                    .logAndIgnoreErrors  { print("Error downloading image: \($0)") }
                )
        }
                
        // RemoteRenderDataType allows defining a type that represents an image on the Internet.
        public struct RenderData: RemoteRenderDataType {
            public let image: Image
            public let size: CGSize
            
            public var imageURL: URL {
                return self.image.url
            }
        }
    }
}

现在,在您的视图中创建一个 ImageView 实例

let view = ImageViews.createView()

您可以将 Image 类型的值分配给它。 这将异步使用渲染器来获取图像并根据需要对其进行处理。

view.data = Image(url: yourUrl)

特性

RendererType 易于组合。 提供了便捷的方法,方便发现

Autocompletion

内存缓存

这提供了一种简单的方法来在内存中缓存已处理或已下载的图像

RemoteImageRenderer<RenderData>()
    .multicasted()

磁盘缓存

首先,您需要使您的 RenderDataType 遵循 DataFileType

public struct RenderData: RenderDataType, DataFileType {
    public let image: Image
    public let size: CGSize
    
    public var uniqueFilename: String {
        return (self.image.url as NSURL)
            .resourceSpecifier!
            .addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
    }
}

然后将缓存层添加到渲染器

RemoteImageRenderer<RenderData>()
    .multicasted()
    .withCache(DiskCache.onCacheSubdirectory("images"))

CacheRenderer 提供了高度的自定义功能,允许您根据需要缓存图像。 请参阅示例,了解更复杂的场景,其中提供了不同的缓存层

Disk Cache

占位符

您可以为您的 AsyncImageView 提供一个占位符渲染器

ImageView(
    initialFrame: .zero,
    renderer: Renderer.singleton.normalImageRenderer,
    placeholderRenderer: Renderer.singleton.placeholderImageRenderer
)

只要 data 设置为 nil,图像视图将使用占位符。

错误处理

AsyncImageView 不会接受可能产生错误的渲染器(这会在编译时检查)。 因此,您需要使用 .logAndIgnoreErrors

或者,您可以在出现错误时使用不同的渲染器(例如,使用 LocalImageRenderer 从磁盘加载图像)

RemoteImageRenderer<RenderData>()
    .fallback(otherRenderer)

其他特性

更多文档将介绍其他特性。 同时,请随意浏览代码以查找更多详细信息

集成

Carthage

如果您使用 Carthage 来管理您的依赖项,只需将 AsyncImageView 添加到您的 Cartfile

github "NachoSoto/AsyncImageView" ~> 5.0

如果您使用 Carthage 构建您的依赖项,请确保您已将 AsyncImageView.frameworkReactiveCocoa.frameworkReactiveSwift.frameworkResult.framework 添加到您的目标的“*Linked Frameworks and Libraries*”部分,并将它们包含在您的 Carthage 框架复制构建阶段中。

有问题吗?

如果您需要任何帮助,请随时在 Twitter 上给我发送私信,或打开一个 GitHub issue