SDWebImageSwiftUI
SDWebImageSwiftUI — это фреймворк для загрузки изображений в SwiftUI, основанный на SDWebImage. Он предоставляет все ваши любимые функции из SDWebImage, такие как асинхронная загрузка изображений, кэширование в памяти и на диске, воспроизведение анимированных изображений и производительность.
Фреймворк предоставляет различные структуры View, API которых соответствует рекомендациям фреймворка SwiftUI. Если вы знакомы с Image, вам будет легко использовать WebImage и AnimatedImage.
Функции
Поскольку SDWebImageSwiftUI построен на основе SDWebImage, он предоставляет как готовые функции, так и расширенные мощные функции, которые могут потребоваться в реальных приложениях. Проверьте нашу Вики, когда вам нужно:
Вы также можете воспользоваться всеми преимуществами существующего сообщества вокруг SDWebImage. Вы можете получить поддержку массовых форматов изображений (GIF/APNG/WebP/HEIF/AVIF/SVG/PDF) через плагины кодера, поддержку PhotoKit через SDWebImagePhotosPlugin, интеграцию с Firebase через FirebaseUI и т. д.
Помимо всех этих функций, мы оптимизируем SwiftUI, например, Binding, View Modifier, используя тот же шаблон проектирования, чтобы стать хорошим гражданином SwiftUI.
Версия
Этот фреймворк активно разрабатывается, рекомендуется по возможности использовать последнюю версию (включая зависимость SDWebImage).
Этот фреймворк следует семантическому управлению версиями. Каждое изменение API, нарушающее работу источника, приводит к основной версии.
Журнал изменений
В этом проекте используется формат ведения журнала изменений, чтобы записывать изменения. Ознакомьтесь с CHANGELOG.md об изменениях между версиями. Изменения также будут обновлены на странице выпуска.
Вклад
Приветствуются все отчёты о проблемах, запросы функций, вклады и звёзды GitHub. Надеемся на активную обратную связь и продвижение, если вы считаете этот фреймворк полезным.
Требования
Совместимость со SwiftUI 2.0
iOS 14 (macOS 11) представляет SwiftUI 2.0, который сохраняет большую часть совместимости API, но изменяет многие внутренние поведения, что нарушает работу SDWebImageSwiftUI.
Начиная с версии 2.0.0 мы используем поведение SwiftUI 2.0 и iOS 14 (macOS 11). Вы можете использовать WebImage и AnimatedImage внутри нового LazyVStack.
var body: some View {
ScrollView {
LazyVStack {
ForEach(urls, id: \.self) { url in
AnimatedImage(url: url)
}
``` ```swift
WebImage(url: url)
.indicator {
Indicator { _, _ in
ProgressView()
}
}
var body: some View {
Group {
AnimatedImage(url: URL(string: "https://raw.githubusercontent.com/liyong03/YLGIFImage/master/YLGIFImageDemo/YLGIFImageDemo/joy.gif"))
// Поддерживает опции и контекст, например `.progressiveLoad` для прогрессивной загрузки анимированных изображений
.onFailure { error in
// Ошибка
}
.resizable() // Изменяемый размер, как SwiftUI.Image, вы должны использовать этот модификатор, иначе представление будет использовать размер растрового изображения изображения
.placeholder(UIImage(systemName: "photo")) // Изображение-заполнитель
// Также поддерживает ViewBuilder
.placeholder {
Circle().foregroundColor(.gray)
}
.indicator(SDWebImageActivityIndicator.medium) // Индикатор активности
.transition(.fade) // Переход с эффектом затухания
.scaledToFit() // Обратите внимание, что это нужно вызывать на AnimatedImage, но не `some View` после View Modifier (метод расширения протокола Swift статически диспетчеризуется)
// Данные
AnimatedImage(data: try! Data(contentsOf: URL(fileURLWithPath: "/tmp/foo.webp")))
.customLoopCount(1) // Пользовательское количество циклов
.playbackRate(2.0) // Скорость воспроизведения
// Пакет (не каталог активов)
AnimatedImage(name: "animation1.gif", isAnimating: $isAnimating) // Управление привязкой к анимации
.maxBufferSize(.max)
.onViewUpdate { view, context in // Расширенная координата нативного представления
// Подсказка AppKit для наведения курсора мыши
view.toolTip = "Mouseover Tip"
// Расширенный режим содержимого UIKit
view.contentMode = .topLeft
// Координатор, используется для привязки Cocoa или метода делегата
let coordinator = context.coordinator
}
}
}
Примечание: AnimatedImage поддерживает как URL-адрес изображения, так и данные изображения для формата анимированного изображения. В основе лежит Animated ImageView от SDWebImage. Обратите внимание, что поскольку это основано на представлении UIKit/AppKit, некоторые расширенные макеты и системы анимации SwiftUI могут работать не так, как ожидалось. Возможно, вам потребуется UIKit/AppKit и Core Animation для изменения нативного представления.
Примечание: некоторые методы AnimatedImage, такие как .transition
, .indicator
и .aspectRatio
, имеют те же имена, что и методы протокола SwiftUI.View. Но аргументы принимают другой тип. Это связано с тем, что AnimatedImage можно использовать с компонентами UIKit/AppKit и анимацией. Если вы обнаружите двусмысленность, используйте полное объявление типа вместо синтаксиса выражения точки.
Примечание: Некоторые методы AnimatedImage возвращают some View, новое модифицированное содержимое. Вы потеряете метод модификатора, связанный с типом. В этом случае вы можете либо изменить порядок вызова метода, либо использовать Native View в .onViewUpdate
для восстановления.
// Использование компонентов UIKit
var body: some View {
AnimatedImage(name: "animation2.gif")
.indicator(SDWebImageProgressIndicator.default) // Компонент индикатора UIKit
.transition(SDWebImageTransition.flipFromLeft) // Анимационный переход UIKit
}
// Использование компонентов SwiftUI
var body: some View {
AnimatedImage(name: "animation2.gif")
.indicator(Indicator.progress) // Компонент индикатора SwiftUI
.transition(AnyTransition.flipFromLeft) // Анимационный переход SwiftUI
}
У нас есть два разных типа представлений, потому что существуют ограничения SwiftUI. Однако мы стремимся предоставить... Лучшее решение для всех случаев использования
Если вам не нужно анимированное изображение, предпочтительнее сначала использовать WebImage. Он работает так же гладко, как и встроенное представление SwiftUI. Если SwiftUI работает, то всё в порядке. Если нет — тоже ничего страшного.
Если вам нужно простое анимированное изображение, используйте WebImage. Оно обеспечивает базовую поддержку анимированных изображений, но не поддерживает прогрессивный рендеринг анимации или векторные изображения, если вас это не волнует.
Если же вам нужна мощная поддержка анимированных изображений, выбирайте AnimatedImage. Помните, что он также поддерживает статические изображения, и вам не нужно проверять формат, просто используйте его как есть. Кроме того, некоторые мощные функции, такие как UIKit/AppKit tint color, векторные изображения и конфигурация символьных изображений, доступны только в AnimatedImage, но пока не в SwfitUI.
Однако, поскольку AnimatedImage использует UIViewRepresentable и управляется UIKit, в настоящее время могут быть небольшие проблемы совместимости между UIKit и системой компоновки и анимации SwiftUI, или ошибки, связанные с самим SwiftUI. Мы стараемся максимально соответствовать поведению SwiftUI и предоставляем тот же API, что и WebImage, что упрощает переключение между этими двумя типами при необходимости.
Используйте ImageManager для вашего собственного типа представления
ImageManager — это класс, который соответствует протоколу ObservableObject от Combine. Это основной источник данных для загрузки WebImage, который мы предоставили.
Для сложных случаев использования, таких как загрузка изображений в сложный граф представлений, которые вы не хотите использовать с WebImage, вы можете напрямую связать свой собственный тип представления с менеджером.
Он похож на SDWebImageManager, но создан для мира SwiftUI и предоставляет источник истины для загрузки изображений. Лучше всего использовать @ObservedObject SwiftUI для привязки каждого экземпляра менеджера к вашему экземпляру представления, что автоматически обновляет тело представления при изменении статуса изображения.
struct MyView : View {
@ObservedObject var imageManager: ImageManager
var body: some View {
// Ваш пользовательский сложный граф представления
Group {
if imageManager.image != nil {
Image(uiImage: imageManager.image!)
} else {
Rectangle().fill(Color.gray)
}
}
// Запуск загрузки изображения при появлении
.onAppear { self.imageManager.load() }
// Отмена загрузки изображения при исчезновении
.onDisappear { self.imageManager.cancel() }
}
}
struct MyView_Previews: PreviewProvider {
static var previews: some View {
MyView(imageManager: ImageManager(url: URL(string: "https://via.placeholder.com/200x200.jpg"))
}
}
Настройка и конфигурация
Этот фреймворк основан на SDWebImage и поддерживает расширенные настройки и конфигурации для удовлетворения потребностей различных пользователей.
Вы можете зарегистрировать несколько плагинов кодера для внешних форматов изображений. Вы можете регистрировать различные кэши (разные пути и конфигурации), загрузчики (URLSession и URL-адреса фотографий). Вы можете контролировать срок действия кэша, размер, приоритет загрузки и т. д. Всё это есть в нашей вики.
Лучшее место для размещения этого кода настройки для приложения SwiftUI — AppDelegate.swift:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Добавляем поддержку WebP/SVG/PDF
SDImageCodersManager.shared.addCoder(SDImageWebPCoder.shared)
SDImageCodersManager.shared.addCoder(SDImageSVGCoder.shared)
SDImageCodersManager.shared.addCoder(SDImagePDFCoder.shared)
// Добавляем стандартный HTTP-заголовок
SDWebImageDownloader.shared.setValue("image/webp,image/apng,image/*,*/*;q=0.8", forHTTPHeaderField: "Accept")
// Добавляем несколько кэшей
let cache = SDImageCache(namespace: "tiny")
cache.config.maxMemoryCost = 100 * 1024 * 1024 // 100 МБ памяти
cache.config.maxDiskSize = 50 * 1024 * 1024 // 50 МБ диска
SDImageCachesManager.shared.addCache(cache)
SDWebImageManager.defaultImageCache = SDImageCachesManager.shared
``` **NSURL.sd_URL(with: asset) as URL?**
// Или через удобное расширение
**let photosURL = asset.sd_URLRepresentation**
Для некоторых пользовательских кодеров вам необходимо запросить изображение с некоторыми опциями для управления поведением, такими как векторные изображения SVG/PDF. Потому что SwiftUI.Image или WebImage вообще не поддерживают векторный график.
let vectorURL: URL? // URL to SVG или PDF
WebImage(url: vectorURL, context: [.imageThumbnailPixelSize: CGSize(width: 100, height: 100)])
let lottieURL: URL? // URL to Lottie.json
WebImage(url: lottieURL, isAnimating: $isAnimating)
Что касается кэшей, на самом деле вам не нужно ни о чём беспокоиться. Это просто работает после настройки.
SDWebImageSwiftUI поддерживает использование, когда цель вашего приложения имеет целевую версию развёртывания меньше, чем iOS 13/macOS 10.15/tvOS 13/watchOS 6. Что позволит слабо компоновать SwiftUI (Combine), чтобы можно было писать код с доступной проверкой во время выполнения.
Чтобы использовать обратную совместимость, вы должны сделать следующее:
Добавьте -weak_framework SwiftUI -weak_framework Combine
в настройку сборки «Другие флаги компоновщика» вашей цели приложения. Вы также можете сделать это, используя флажок Xcode «Необязательный фреймворк», эффект будет тот же.
Обратите внимание, что все сторонние фреймворки SwiftUI должны иметь эту настройку сборки, а не только SDWebImageSwiftUI. Иначе при запуске на устройстве iOS 12 возникнет ошибка dyld во время запуска.
Для версии развёртывания ниже iOS 12.2 (первая версия, в которой Swift 5 Runtime был включён в систему iOS), вам нужно изменить минимальную версию развёртывания SDWebImageSwiftUI. Это может вызвать некоторые побочные эффекты в оптимизации компилятора и вызвать массовые предупреждения для некоторых фреймворков.
Однако для iOS 12.2+ вы всё равно можете оставить минимальную версию развёртывания равной iOS 13, никаких дополнительных предупреждений или замедления производительности для клиента iOS 13.
Потому что Swift использует минимальную версию развёртывания, чтобы определить, компоновать ли приложение со встроенным Swift или с системным (/usr/lib/swift/libswiftCore.dylib
).
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0' # нужная вам версия
end
end
end
Для пользователя Carthage вы можете использовать carthage update --no-build
, чтобы загрузить зависимость, затем изменить версию Xcode Project и собрать бинарный фреймворк.
Для пользователя SwiftPM вы должны использовать локальную зависимость (с подмодулем Git), чтобы изменить версию развёртывания.
Для пользователя Carthage созданный бинарный фреймворк будет использовать Library Evolution, чтобы поддерживать обратную совместимость.
Для пользователя CocoaPods вы можете пропустить проверку версии платформы в Podfile, добавив:
platform :ios, '13.0' # Это не влияет на версию развёртывания вашей цели, просто подсказка для CocoaPods
Добавьте весь код SwiftUI с доступной аннотацией и проверкой времени выполнения, например так:
// AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// ...
if #available(iOS 13, *) {
window.rootViewController = UIHostingController(rootView: ContentView())
} else {
window.rootViewController = ViewController()
}
// ...
}
// ViewController.swift
class ViewController: UIViewController {
var label: UILabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )