Agrume

Build Status Carthage compatible Version License Platform SPM

一个用 Swift 编写的 iOS 图片查看器,支持多张图片。

Agrume

要求

安装

使用 Swift Package Manager

或者使用 CocoaPods。 将依赖项添加到您的 Podfile 中,然后运行 pod install

pod "Agrume"

或者使用 Carthage。 将依赖项添加到您的 Cartfile 中,然后运行 carthage update

github "JanGorman/Agrume"

用法

您可以通过多种方式使用图片查看器(包含的示例项目展示了所有方式)。

对于单张图片,使用起来非常简单,如下:

基本用法

import Agrume

private lazy var agrume = Agrume(image: UIImage(named: "")!)

@IBAction func openImage(_ sender: Any) {
  agrume.show(from: self)
}

您也可以传入一个 URL,Agrume 将会负责下载。

SwiftUI

目前,SwiftUI 实现没有公开配置,所以只能用作基本的图片查看器 - 欢迎提交 PR 来扩展其功能。

import Agrume

struct ExampleView: View {
    
  let images: [UIImage]

  @State var showAgrume = false

  var body: some View {
    VStack {
      // Hide the presenting button (or other view) whenever Agrume is shown
      if !showAgrume {
        Button("Launch Agrume from SwiftUI") {
          withAnimation {
            showAgrume = true
          }
        }
      }

      if showAgrume {
        // You can pass a single or multiple images
        AgrumeView(images: images, isPresenting: $showAgrume)
      }
    }
  }
}

背景配置

Agrume 具有不同的背景配置。您可以模糊它所覆盖的视图,或者提供背景颜色。

let agrume = Agrume(image: UIImage(named: "")!, background: .blurred(.regular))
// or
let agrume = Agrume(image: UIImage(named: "")!, background: .colored(.green))

多张图片

如果您正在显示一个 UICollectionView 并且想要添加缩放支持,您也可以使用图片或 URL 的数组来调用 Agrume。

// In case of an array of [UIImage]:
let agrume = Agrume(images: images, startIndex: indexPath.item, background: .blurred(.light))
// Or an array of [URL]:
// let agrume = Agrume(urls: urls, startIndex: indexPath.item, background: .blurred(.light))

agrume.didScroll = { [unowned self] index in
  self.collectionView.scrollToItem(at: IndexPath(item: index, section: 0), at: [], animated: false)
}
agrume.show(from: self)

这展示了一种保持缩放后的库和背景中的库同步的方法。

动画 GIF

Agrume 捆绑了 SwiftyGif 来显示动画 GIF。 您可以使用 SwiftyGif 的自定义 UIImage 初始化器。

let image = UIImage(gifName: "animated.gif")
let agrume = Agrume(image: image)
agrume.display(from: self)

// Or gif using data:

let image = UIImage(gifData: data)
let agrume = Agrume(image: image)

// Or multiple images:

let images = [UIImage(gifName: "animated.gif"), UIImage(named: "foo.png")] // You can pass both animated and regular images at the same time
let agrume = Agrume(images: images)

支持远程动画 GIF(即使用 URL 或 URL 列表初始化器)。Agrume 会进行图像类型检测并正确显示它们。如果从自定义 UIImageView 使用 Agrume,您可能需要使用原始数据重建 UIImage 以保留动画,而不是使用图像视图中的 UIImage 实例。

关闭按钮

默认情况下,您可以通过拖动/滑动图像离开屏幕来关闭缩放视图。您可以选择不使用此行为,而是显示一个关闭按钮。 为了匹配您的应用程序的外观和风格,您可以传入一个自定义的 UIBarButtonItem

// Default button that displays NSLocalizedString("Close", …)
let agrume = Agrume(image: UIImage(named: "")!, .dismissal: .withButton(nil))
// Customise the button any way you like. For example display a system "x" button
let button = UIBarButtonItem(barButtonSystemItem: .stop, target: nil, action: nil)
button.tintColor = .red
let agrume = Agrume(image: UIImage(named: "")!, .dismissal: .withButton(button))

包含的示例应用程序显示了这两种情况,供您参考。

自定义下载处理程序

如果您想控制图像的下载(例如,为了缓存),您还可以设置一个下载闭包,该闭包回调 Agrume 以设置图像。 例如,让我们使用 MapleBacon

import Agrume
import MapleBacon

private lazy var agrume = Agrume(url: URL(string: "https://dl.dropboxusercontent.com/u/512759/MapleBacon.png")!)

@IBAction func openURL(_ sender: Any) {
  agrume.download = { url, completion in
    Downloader.default.download(url) { image in
      completion(image)
    }
  }
  agrume.show(from: self)
}

全局自定义下载处理程序

您不必在每个实例的基础上定义处理程序,而是可以在 AgrumeServiceLocator 上设置一个处理程序。 Agrume 将对所有下载使用此处理程序,除非如上所述在实例上覆盖。

import Agrume

AgrumeServiceLocator.shared.setDownloadHandler { url, completion in
  // Download data, cache it and call the completion with the resulting UIImage
}

// Some other place
agrume.show(from: self)

自定义数据源

对于更动态的库需求,您可以实现 AgrumeDataSource 协议,该协议向 Agrume 提供图像。 Agrume 将查询数据源以获取图像数量,如果该数量发生变化,则重新加载其滚动图像视图。

import Agrume

let dataSource: AgrumeDataSource = MyDataSourceImplementation()
let agrume = Agrume(dataSource: dataSource)

agrume.show(from: self)

状态栏外观

您可以在显示缩放视图时自定义状态栏外观。 Agrume 具有一个 statusBarStyle 属性。

let agrume = Agrume(image: image)
agrume.statusBarStyle = .lightContent
agrume.show(from: self)

长按手势和下载图像

如果您想处理图像上的长按手势,可以使用一个可选的 onLongPress 闭包。 这将传递一个可选的 UIImage 和对 Agrume UIViewController 的引用作为参数。 该项目包含一个帮助程序类,可以轻松选择将图像下载到用户的照片库中,称为 AgrumePhotoLibraryHelper。 首先,创建一个 helper 的实例:

private func makeHelper() -> AgrumePhotoLibraryHelper {
  let saveButtonTitle = NSLocalizedString("Save Photo", comment: "Save Photo")
  let cancelButtonTitle = NSLocalizedString("Cancel", comment: "Cancel")
  let helper = AgrumePhotoLibraryHelper(saveButtonTitle: saveButtonTitle, cancelButtonTitle: cancelButtonTitle) { error in
    guard error == nil else {
      print("Could not save your photo")
      return
    }
    print("Photo has been saved to your library")
  }
  return helper
}

然后将此 helper 的长按处理程序传递给 Agrume,如下所示:

let helper = makeHelper()
agrume.onLongPress = helper.makeSaveToLibraryLongPressGesture

自定义覆盖视图

您可以自定义图像视图的外观和功能。 为此,您需要创建一个继承自 AgrumeOverlayView: UIView 的类。 由于这只是一个普通的 UIView,您可以对其执行任何操作,例如向其添加自定义工具栏或按钮。 示例应用程序显示了如何实现此目的的详细示例。

Live Text 支持

Agrume 支持 iOS 16 中引入的 Live Text。 这允许用户与图像中的文本和 QR 码进行交互。 它适用于 iOS 16 或更新版本,以及配备 A12 Bionic 芯片(iPhone XS)或更新版本的设备。

let agrume = Agrume(image: UIImage(named: "")!, enableLiveText: true)

生命周期

Agrume 提供了以下生命周期闭包,您可以选择设置:

运行示例代码

该项目附带一个示例应用程序,该应用程序显示了上面记录的不同功能。 由于依赖于 SwiftyGif,您还需要获取该库才能运行该项目。 它作为 git 子模块包含在内。 在获取存储库后,从项目的根目录运行:

git submodule update --init

许可

Agrume 在 MIT 许可下发布。 有关详细信息,请参阅 LICENSE。