1656610440
为了响应消费者对使用表情符号和 GIF 进行交流的兴趣,越来越多的公司将动画 GIF 整合到他们的电子邮件活动、网站和移动应用程序中,以提高参与度和销售额。
图形交换格式文件是按顺序播放的图像集合,它们看起来像是在移动。GIF 可用于分享演示、突出产品功能或更改、说明用例或展示品牌个性。
许多流行的聊天应用程序(例如 iMessage 和 WhatsApp)以及社交平台(例如 Reddit 或 Twitter)都支持发送和接收 GIF。那么,iOS 应用程序呢?好吧,在撰写本文时,没有原生内置支持在 SwiftUI 或 UIKit 中使用 GIF。
为 iOS 构建一个高效的 GIF 图像加载器需要大量的时间和精力,但幸运的是,一些第三方框架是高性能的,可以在没有任何帧延迟的情况下显示 GIF。
在本文中,我们将演示如何使用流行的 GIF 库,即 Flipboard 的FLAnimatedImage,只需几行代码即可将 GIF 添加到您的 iOS 应用程序中。在本文的演示部分,我们将使用来自GIPHY的 GIF ,这是一个提供各种动画 GIF 的流行数据库。
让我们开始吧,学习如何在我们的应用程序中包含一些令人惊叹的 GIF!
以下三个依赖管理器中的任何一个都可用于将 FLAnimatedImage 添加到项目中:
要将 FLAnimatedImage 添加到使用 CocoaPods 的项目中,请将以下代码添加到 Podfile:
pod 'FLAnimatedImage'
然后,转到终端的项目目录并安装 pod,如下所示:
pod install
要使用 Carthage 将 FLAnimatedImage 添加到项目中,请在 Cartfile 中添加以下代码:
github "Flipboard/FLAnimatedImage"
然后,要仅更新此库,请转到终端的项目目录并运行以下命令:
carthage update FLAnimatedImage
要使用 Swift Package Manager 将 FLAnimatedImage 添加到项目中,请打开 Xcode,转到菜单栏,然后选择File > Add Packages。接下来,将以下链接粘贴到项目 URL 字段中:
https://github.com/Flipboard/FLAnimatedImage
然后,单击Next并选择要添加库的项目目标。单击继续,您已添加FLAnimatedImage
到项目中!
FLAnimatedImage的GitHub存储库中的示例是用 Objective-C 编写的:
#import "FLAnimatedImage.h"
FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif"]]];
FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];
imageView.animatedImage = image;
imageView.frame = CGRectMake(0.0, 0.0, 100.0, 100.0);
[self.view addSubview:imageView];
我们想在 SwiftUI 框架中使用 FLAnimatedImage,但在这样做之前,我们应该了解这个库的两个主要类:
FLAnimatedImage
FLAnimatedImageView
FLAnimatedImage
班级FLAnimatedImage
是一个帮助以高性能方式传递帧的类。我们使用它来设置FLAnimatedImageView
类的图像属性。
要加载 GIF 图像,我们将 GIF 转换为Data
值类型。FLAnimatedImage
有一个接受这个的初始化程序Data
:
convenience init(animatedGIFData data: Data!)
创建类型的图像的实例后FLAnimatedImage
,我们可以使用它来设置图像的属性FLAnimatedImageView
。
imageView.animatedImage
FLAnimatedImageView
班级FLAnimatedImageView
是 的子类UIImageView
并采用FLAnimatedImage
.
类 FLAnimatedImageView
FLAnimatedImageView
自动在视图层次结构中播放 GIF,并在它被删除时停止。animatedImage
我们可以通过访问属性来设置动画图像。
现在我们已经熟悉了 FLAnimatedImage 类及其用法,我们可以将上面的 Objective-C 示例翻译成 Swift,如下所示:
let url = URL(string: "https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif")!
let data = try! Data(contentsOf: url)
/// Creating an animated image from the given animated GIF data
let animatedImage = FLAnimatedImage(animatedGIFData: data)
/// Creating the image view
let imageView = FLAnimatedImageView()
/// Setting the animated image to the image view
imageView.animatedImage = animatedImage
imageView.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
view.addSubview(imageView)
这个例子与 UIKit 相关。将 FLAnimatedImage 与 UIKit 一起使用非常容易,因为它是原生的。但是,要在 SwiftUI 中使用 FLAnimatedImage,我们必须创建一个自定义视图,以利用UIViewRepresentable
UIKit 视图的包装器,将其集成到 SwiftUI 视图层次结构中。
所以,让我们创建我们的自定义视图来简化使用 FLAnimatedImage!
我们将在 SwiftUI 中创建一个名为 的自定义视图GIFView
,它可以帮助我们从本地资源和远程 URL 加载 GIF。
在创建自定义视图之前,让我们创建一个URLType
定义两种情况的枚举:
name
: 本地文件名url
:必须从服务器获取的 GIF 的 URLenum URLType {
case name(String)
case url(URL)
var url: URL? {
switch self {
case .name(let name):
return Bundle.main.url(forResource: name, withExtension: "gif")
case .url(let remoteURL):
return remoteURL
}
}
}
url
在上面的代码中,如果我们同时提供远程 URL 和 GIF 的名称,我们可以看到还有一个返回本地 URL 的计算属性。
我们创建一个新文件,GIFView.swift
. 在这个文件中,我们将导入FLAnimatedImage
库:
import FLAnimatedImage
接下来,我们创建一个struct
符合UIViewRepresentable
协议的 GIFView。此结构有一个采用 URL 类型的初始化程序:
struct GIFView: UIViewRepresentable {
private var type: URLType
init(type: URLType) {
self.type = type
}
}
FLAnimatedImageView
然后,我们添加两个闭包,一个and的实例UIActivityIndicatorView
,以在 GIF 加载时显示活动指示器:
private let imageView: FLAnimatedImageView = {
let imageView = FLAnimatedImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.layer.cornerRadius = 24
imageView.layer.masksToBounds = true
return imageView
}()
private let activityIndicator: UIActivityIndicatorView = {
let activityIndicator = UIActivityIndicatorView()
activityIndicator.translatesAutoresizingMaskIntoConstraints = false
return activityIndicator
}()
在上面的代码中,我们24
为FLAnimatedImageView
圆角半径指定了一个值,但我们可以根据需要自定义它。
该UIViewRepresentable
协议有两个必须实现的必需方法。第一个,makeUIView(context:)
创建视图对象UIView
,并配置初始状态。第二个,updateUIView(_:context:)
更新指定视图的状态。
在该makeUIView(context:)
方法中,我们:
UIView
makeUIView(context:)
和updateUIView(_:context:)
, 添加到UIView
as 子视图UIView
这是该makeUIView(context:)
方法的代码:
func makeUIView(context: Context) -> UIView {
let view = UIView(frame: .zero)
view.addSubview(activityIndicator)
view.addSubview(imageView)
imageView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
imageView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
activityIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
activityIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
return view
}
在该updateUIView(_:context:)
方法中,我们:
Data
包含 URL 内容的实例FLAnimatedImage
传递动画 GIF 数据的实例FLAnimatedView
的动画图像属性设置为获取的图像这是该updateUIView(_:context:)
方法的代码:
func updateUIView(_ uiView: UIView, context: Context) {
activityIndicator.startAnimating()
guard let url = type.url else { return }
DispatchQueue.global().async {
if let data = try? Data(contentsOf: url) {
let image = FLAnimatedImage(animatedGIFData: data)
DispatchQueue.main.async {
activityIndicator.stopAnimating()
imageView.animatedImage = image
}
}
}
}
该图像需要时间来加载动画 GIF 日期,因此我们在并发线程上在后台运行它以避免阻塞 UI。然后,我们在主线程上设置图像。
这是 的最终代码GIFView
:
import SwiftUI
import FLAnimatedImage
struct GIFView: UIViewRepresentable {
private var type: URLType
init(type: URLType) {
self.type = type
}
private let imageView: FLAnimatedImageView = {
let imageView = FLAnimatedImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.layer.cornerRadius = 24
imageView.layer.masksToBounds = true
return imageView
}()
private let activityIndicator: UIActivityIndicatorView = {
let activityIndicator = UIActivityIndicatorView()
activityIndicator.translatesAutoresizingMaskIntoConstraints = false
return activityIndicator
}()
}
extension GIFView {
func makeUIView(context: Context) -> UIView {
let view = UIView(frame: .zero)
view.addSubview(activityIndicator)
view.addSubview(imageView)
imageView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
imageView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
activityIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
activityIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
return view
}
func updateUIView(_ uiView: UIView, context: Context) {
activityIndicator.startAnimating()
guard let url = type.url else { return }
DispatchQueue.global().async {
if let data = try? Data(contentsOf: url) {
let image = FLAnimatedImage(animatedGIFData: data)
DispatchQueue.main.async {
activityIndicator.stopAnimating()
imageView.animatedImage = image
}
}
}
}
}
现在我们有了一个用于 SwiftUI 的视图FLAnimatedImage
,它在 SwiftUI 中的使用就像在 UIKit 中一样容易。
让我们探索两个简单的示例,以及一个更复杂的真实示例。
我们将从资产文件夹中存在的 GIF 的简单示例开始。首先,下载happy-work-from-home
我们将在本例中使用的 GIF 。
我们GIFView
使用前面描述的方法创建 。接下来,我们所要做的就是传入 GIF 的名称,如下所示:
struct ContentView: View {
var body: some View {
GIFView(type: .name("happy-work-from-home"))
.frame(maxHeight: 300)
.padding()
}
}
在模拟器上运行此代码为我们提供了一个动画 GIF:
这是另一个使用相同 GIF 的示例,但从远程 URL 获取它:
struct ContentView: View {
var body: some View {
GIFView(type: .url(URL(string: "https://media.giphy.com/media/Dh5q0sShxgp13DwrvG/giphy.gif")!))
.frame(maxHeight: 300)
.padding()
}
}
如果我们在模拟器上运行此代码,我们将看到一个动画 GIF。请注意,在获取 GIF 时,屏幕会显示一个活动指示器:
现在,让我们继续看一个更复杂的真实示例!
为了充分利用 FLAnimatedImage,让我们探索一个同时加载多个 GIF 的示例。此示例将通过在大量 GIF 中平滑地显示和滚动来演示此框架在内存压力下的性能。
GIPHY是最大的 GIF 市场。它还有一个开发人员程序,允许我们使用提供的 API 获取他们的数据。我们将使用其中一个 API 来获取趋势 GIF 并将它们显示在列表中。
首先,在这里创建一个 GIPHY 帐户。登录后,点击Create New App并选择API。然后,输入您的应用名称和描述,并确认协议。接下来,单击Create App按钮并记下API Key。
趋势端点返回当天最相关和最吸引人的内容列表。它看起来像这样:
http://api.giphy.com/v1/gifs/trending
对于身份验证,我们将 API 密钥作为参数传递。我们还可以通过使用limit
参数来限制一个响应中的 GIF 数量并offset
获取下一组响应。
端点返回一个巨大的 JSON 文件,但我们将对其进行精简以用于我们的要求。为此,请创建另一个文件,GIFs.swift
并添加以下代码:
import Foundation
struct GIFs: Codable {
let data: [GIF]
}
struct GIF: Codable, Identifiable {
let id: String
let title: String
let images: Images
}
struct Images: Codable {
let original: GIFURL
}
struct GIFURL: Codable {
let url: String
}
端点返回一个 数组GIF
,每个数组GIF
都有一个标题和一个图像 URL。
继续创建 UI,我们添加一个变量来存储 GIF 并跟踪offset
. 这个想法是,当我们使用下拉刷新手势刷新屏幕时,它会获取下一批数据:
struct ContentView: View {
@State private var gifs: [GIF] = []
@State private var offset = 0
}
接下来,我们将添加一个从趋势端点获取 GIF 数据的方法:
extension ContentView {
private func fetchGIFs() async {
do {
try await fetchGIFData(offset: offset)
} catch {
print(error)
}
}
private func fetchGIFData(for limit: Int = 10, offset: Int) async throws {
var components = URLComponents()
components.scheme = "https"
components.host = "api.giphy.com"
components.path = "/v1/gifs/trending"
components.queryItems = [
.init(name: "api_key", value: "<API KEY>"), // <-- ADD THE API KEY HERE
.init(name: "limit", value: "\(limit)"),
.init(name: "offset", value: "\(offset)")
]
guard let url = components.url else {
throw URLError(.badURL)
}
let (data, _) = try await URLSession.shared.data(from: url)
gifs = try JSONDecoder().decode(GIFs.self, from: data).data
}
}
上面的代码执行以下操作:
api_key
、limit
和offset
GIFs
结构对其进行解码gifs
对于 UI,我们有一个列表,可以加载数组gifs
并在其中显示单个 GIF,该列表GIFView
采用 URL:
extension ContentView {
var body: some View {
NavigationView {
if gifs.isEmpty {
VStack(spacing: 10) {
ProgressView()
Text("Loading your favorite GIFs...")
}
} else {
List(gifs) { gif in
if let url = URL(string: gif.images.original.url) {
GIFView(type: .url(url))
.frame(minHeight: 200)
.listRowSeparator(.hidden)
}
}
.listStyle(.plain)
.navigationTitle("GIPHY")
}
}
.navigationViewStyle(.stack)
.task {
await fetchGIFs()
}
.refreshable {
offset += 10
await fetchGIFs()
}
}
}
当通过下拉屏幕刷新视图时,它会增加offset
by 10
,获取新的 GIF 并更新屏幕。
这是一个屏幕记录,显示了刷新视图时发生的情况:
有了这个,我们创建了一个完整的高性能应用程序,显示来自 GIPHY 的趋势 GIF!
我们必须付出很多努力来创建UIImageView
用于处理 GIF 的高性能动画。或者,我们可以利用现有的 FLAnimatedImage 框架,该框架已被 Facebook、Instagram、Slack 和 Telegram 等许多流行应用程序使用。
使用自定义GIFView
,我们只需要 SwiftUI 中的一行代码就可以在我们的应用程序中显示惊人的 GIF!玩得开心实验和编码!动画 GIF 只是增强 iOS 应用的 UX 和 UI的众多方法之一。
来源:https ://blog.logrocket.com/adding-gifs-ios-app-flanitatedimage-swiftui/
1656610440
为了响应消费者对使用表情符号和 GIF 进行交流的兴趣,越来越多的公司将动画 GIF 整合到他们的电子邮件活动、网站和移动应用程序中,以提高参与度和销售额。
图形交换格式文件是按顺序播放的图像集合,它们看起来像是在移动。GIF 可用于分享演示、突出产品功能或更改、说明用例或展示品牌个性。
许多流行的聊天应用程序(例如 iMessage 和 WhatsApp)以及社交平台(例如 Reddit 或 Twitter)都支持发送和接收 GIF。那么,iOS 应用程序呢?好吧,在撰写本文时,没有原生内置支持在 SwiftUI 或 UIKit 中使用 GIF。
为 iOS 构建一个高效的 GIF 图像加载器需要大量的时间和精力,但幸运的是,一些第三方框架是高性能的,可以在没有任何帧延迟的情况下显示 GIF。
在本文中,我们将演示如何使用流行的 GIF 库,即 Flipboard 的FLAnimatedImage,只需几行代码即可将 GIF 添加到您的 iOS 应用程序中。在本文的演示部分,我们将使用来自GIPHY的 GIF ,这是一个提供各种动画 GIF 的流行数据库。
让我们开始吧,学习如何在我们的应用程序中包含一些令人惊叹的 GIF!
以下三个依赖管理器中的任何一个都可用于将 FLAnimatedImage 添加到项目中:
要将 FLAnimatedImage 添加到使用 CocoaPods 的项目中,请将以下代码添加到 Podfile:
pod 'FLAnimatedImage'
然后,转到终端的项目目录并安装 pod,如下所示:
pod install
要使用 Carthage 将 FLAnimatedImage 添加到项目中,请在 Cartfile 中添加以下代码:
github "Flipboard/FLAnimatedImage"
然后,要仅更新此库,请转到终端的项目目录并运行以下命令:
carthage update FLAnimatedImage
要使用 Swift Package Manager 将 FLAnimatedImage 添加到项目中,请打开 Xcode,转到菜单栏,然后选择File > Add Packages。接下来,将以下链接粘贴到项目 URL 字段中:
https://github.com/Flipboard/FLAnimatedImage
然后,单击Next并选择要添加库的项目目标。单击继续,您已添加FLAnimatedImage
到项目中!
FLAnimatedImage的GitHub存储库中的示例是用 Objective-C 编写的:
#import "FLAnimatedImage.h"
FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif"]]];
FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];
imageView.animatedImage = image;
imageView.frame = CGRectMake(0.0, 0.0, 100.0, 100.0);
[self.view addSubview:imageView];
我们想在 SwiftUI 框架中使用 FLAnimatedImage,但在这样做之前,我们应该了解这个库的两个主要类:
FLAnimatedImage
FLAnimatedImageView
FLAnimatedImage
班级FLAnimatedImage
是一个帮助以高性能方式传递帧的类。我们使用它来设置FLAnimatedImageView
类的图像属性。
要加载 GIF 图像,我们将 GIF 转换为Data
值类型。FLAnimatedImage
有一个接受这个的初始化程序Data
:
convenience init(animatedGIFData data: Data!)
创建类型的图像的实例后FLAnimatedImage
,我们可以使用它来设置图像的属性FLAnimatedImageView
。
imageView.animatedImage
FLAnimatedImageView
班级FLAnimatedImageView
是 的子类UIImageView
并采用FLAnimatedImage
.
类 FLAnimatedImageView
FLAnimatedImageView
自动在视图层次结构中播放 GIF,并在它被删除时停止。animatedImage
我们可以通过访问属性来设置动画图像。
现在我们已经熟悉了 FLAnimatedImage 类及其用法,我们可以将上面的 Objective-C 示例翻译成 Swift,如下所示:
let url = URL(string: "https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif")!
let data = try! Data(contentsOf: url)
/// Creating an animated image from the given animated GIF data
let animatedImage = FLAnimatedImage(animatedGIFData: data)
/// Creating the image view
let imageView = FLAnimatedImageView()
/// Setting the animated image to the image view
imageView.animatedImage = animatedImage
imageView.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
view.addSubview(imageView)
这个例子与 UIKit 相关。将 FLAnimatedImage 与 UIKit 一起使用非常容易,因为它是原生的。但是,要在 SwiftUI 中使用 FLAnimatedImage,我们必须创建一个自定义视图,以利用UIViewRepresentable
UIKit 视图的包装器,将其集成到 SwiftUI 视图层次结构中。
所以,让我们创建我们的自定义视图来简化使用 FLAnimatedImage!
我们将在 SwiftUI 中创建一个名为 的自定义视图GIFView
,它可以帮助我们从本地资源和远程 URL 加载 GIF。
在创建自定义视图之前,让我们创建一个URLType
定义两种情况的枚举:
name
: 本地文件名url
:必须从服务器获取的 GIF 的 URLenum URLType {
case name(String)
case url(URL)
var url: URL? {
switch self {
case .name(let name):
return Bundle.main.url(forResource: name, withExtension: "gif")
case .url(let remoteURL):
return remoteURL
}
}
}
url
在上面的代码中,如果我们同时提供远程 URL 和 GIF 的名称,我们可以看到还有一个返回本地 URL 的计算属性。
我们创建一个新文件,GIFView.swift
. 在这个文件中,我们将导入FLAnimatedImage
库:
import FLAnimatedImage
接下来,我们创建一个struct
符合UIViewRepresentable
协议的 GIFView。此结构有一个采用 URL 类型的初始化程序:
struct GIFView: UIViewRepresentable {
private var type: URLType
init(type: URLType) {
self.type = type
}
}
FLAnimatedImageView
然后,我们添加两个闭包,一个and的实例UIActivityIndicatorView
,以在 GIF 加载时显示活动指示器:
private let imageView: FLAnimatedImageView = {
let imageView = FLAnimatedImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.layer.cornerRadius = 24
imageView.layer.masksToBounds = true
return imageView
}()
private let activityIndicator: UIActivityIndicatorView = {
let activityIndicator = UIActivityIndicatorView()
activityIndicator.translatesAutoresizingMaskIntoConstraints = false
return activityIndicator
}()
在上面的代码中,我们24
为FLAnimatedImageView
圆角半径指定了一个值,但我们可以根据需要自定义它。
该UIViewRepresentable
协议有两个必须实现的必需方法。第一个,makeUIView(context:)
创建视图对象UIView
,并配置初始状态。第二个,updateUIView(_:context:)
更新指定视图的状态。
在该makeUIView(context:)
方法中,我们:
UIView
makeUIView(context:)
和updateUIView(_:context:)
, 添加到UIView
as 子视图UIView
这是该makeUIView(context:)
方法的代码:
func makeUIView(context: Context) -> UIView {
let view = UIView(frame: .zero)
view.addSubview(activityIndicator)
view.addSubview(imageView)
imageView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
imageView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
activityIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
activityIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
return view
}
在该updateUIView(_:context:)
方法中,我们:
Data
包含 URL 内容的实例FLAnimatedImage
传递动画 GIF 数据的实例FLAnimatedView
的动画图像属性设置为获取的图像这是该updateUIView(_:context:)
方法的代码:
func updateUIView(_ uiView: UIView, context: Context) {
activityIndicator.startAnimating()
guard let url = type.url else { return }
DispatchQueue.global().async {
if let data = try? Data(contentsOf: url) {
let image = FLAnimatedImage(animatedGIFData: data)
DispatchQueue.main.async {
activityIndicator.stopAnimating()
imageView.animatedImage = image
}
}
}
}
该图像需要时间来加载动画 GIF 日期,因此我们在并发线程上在后台运行它以避免阻塞 UI。然后,我们在主线程上设置图像。
这是 的最终代码GIFView
:
import SwiftUI
import FLAnimatedImage
struct GIFView: UIViewRepresentable {
private var type: URLType
init(type: URLType) {
self.type = type
}
private let imageView: FLAnimatedImageView = {
let imageView = FLAnimatedImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.layer.cornerRadius = 24
imageView.layer.masksToBounds = true
return imageView
}()
private let activityIndicator: UIActivityIndicatorView = {
let activityIndicator = UIActivityIndicatorView()
activityIndicator.translatesAutoresizingMaskIntoConstraints = false
return activityIndicator
}()
}
extension GIFView {
func makeUIView(context: Context) -> UIView {
let view = UIView(frame: .zero)
view.addSubview(activityIndicator)
view.addSubview(imageView)
imageView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
imageView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
activityIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
activityIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
return view
}
func updateUIView(_ uiView: UIView, context: Context) {
activityIndicator.startAnimating()
guard let url = type.url else { return }
DispatchQueue.global().async {
if let data = try? Data(contentsOf: url) {
let image = FLAnimatedImage(animatedGIFData: data)
DispatchQueue.main.async {
activityIndicator.stopAnimating()
imageView.animatedImage = image
}
}
}
}
}
现在我们有了一个用于 SwiftUI 的视图FLAnimatedImage
,它在 SwiftUI 中的使用就像在 UIKit 中一样容易。
让我们探索两个简单的示例,以及一个更复杂的真实示例。
我们将从资产文件夹中存在的 GIF 的简单示例开始。首先,下载happy-work-from-home
我们将在本例中使用的 GIF 。
我们GIFView
使用前面描述的方法创建 。接下来,我们所要做的就是传入 GIF 的名称,如下所示:
struct ContentView: View {
var body: some View {
GIFView(type: .name("happy-work-from-home"))
.frame(maxHeight: 300)
.padding()
}
}
在模拟器上运行此代码为我们提供了一个动画 GIF:
这是另一个使用相同 GIF 的示例,但从远程 URL 获取它:
struct ContentView: View {
var body: some View {
GIFView(type: .url(URL(string: "https://media.giphy.com/media/Dh5q0sShxgp13DwrvG/giphy.gif")!))
.frame(maxHeight: 300)
.padding()
}
}
如果我们在模拟器上运行此代码,我们将看到一个动画 GIF。请注意,在获取 GIF 时,屏幕会显示一个活动指示器:
现在,让我们继续看一个更复杂的真实示例!
为了充分利用 FLAnimatedImage,让我们探索一个同时加载多个 GIF 的示例。此示例将通过在大量 GIF 中平滑地显示和滚动来演示此框架在内存压力下的性能。
GIPHY是最大的 GIF 市场。它还有一个开发人员程序,允许我们使用提供的 API 获取他们的数据。我们将使用其中一个 API 来获取趋势 GIF 并将它们显示在列表中。
首先,在这里创建一个 GIPHY 帐户。登录后,点击Create New App并选择API。然后,输入您的应用名称和描述,并确认协议。接下来,单击Create App按钮并记下API Key。
趋势端点返回当天最相关和最吸引人的内容列表。它看起来像这样:
http://api.giphy.com/v1/gifs/trending
对于身份验证,我们将 API 密钥作为参数传递。我们还可以通过使用limit
参数来限制一个响应中的 GIF 数量并offset
获取下一组响应。
端点返回一个巨大的 JSON 文件,但我们将对其进行精简以用于我们的要求。为此,请创建另一个文件,GIFs.swift
并添加以下代码:
import Foundation
struct GIFs: Codable {
let data: [GIF]
}
struct GIF: Codable, Identifiable {
let id: String
let title: String
let images: Images
}
struct Images: Codable {
let original: GIFURL
}
struct GIFURL: Codable {
let url: String
}
端点返回一个 数组GIF
,每个数组GIF
都有一个标题和一个图像 URL。
继续创建 UI,我们添加一个变量来存储 GIF 并跟踪offset
. 这个想法是,当我们使用下拉刷新手势刷新屏幕时,它会获取下一批数据:
struct ContentView: View {
@State private var gifs: [GIF] = []
@State private var offset = 0
}
接下来,我们将添加一个从趋势端点获取 GIF 数据的方法:
extension ContentView {
private func fetchGIFs() async {
do {
try await fetchGIFData(offset: offset)
} catch {
print(error)
}
}
private func fetchGIFData(for limit: Int = 10, offset: Int) async throws {
var components = URLComponents()
components.scheme = "https"
components.host = "api.giphy.com"
components.path = "/v1/gifs/trending"
components.queryItems = [
.init(name: "api_key", value: "<API KEY>"), // <-- ADD THE API KEY HERE
.init(name: "limit", value: "\(limit)"),
.init(name: "offset", value: "\(offset)")
]
guard let url = components.url else {
throw URLError(.badURL)
}
let (data, _) = try await URLSession.shared.data(from: url)
gifs = try JSONDecoder().decode(GIFs.self, from: data).data
}
}
上面的代码执行以下操作:
api_key
、limit
和offset
GIFs
结构对其进行解码gifs
对于 UI,我们有一个列表,可以加载数组gifs
并在其中显示单个 GIF,该列表GIFView
采用 URL:
extension ContentView {
var body: some View {
NavigationView {
if gifs.isEmpty {
VStack(spacing: 10) {
ProgressView()
Text("Loading your favorite GIFs...")
}
} else {
List(gifs) { gif in
if let url = URL(string: gif.images.original.url) {
GIFView(type: .url(url))
.frame(minHeight: 200)
.listRowSeparator(.hidden)
}
}
.listStyle(.plain)
.navigationTitle("GIPHY")
}
}
.navigationViewStyle(.stack)
.task {
await fetchGIFs()
}
.refreshable {
offset += 10
await fetchGIFs()
}
}
}
当通过下拉屏幕刷新视图时,它会增加offset
by 10
,获取新的 GIF 并更新屏幕。
这是一个屏幕记录,显示了刷新视图时发生的情况:
有了这个,我们创建了一个完整的高性能应用程序,显示来自 GIPHY 的趋势 GIF!
我们必须付出很多努力来创建UIImageView
用于处理 GIF 的高性能动画。或者,我们可以利用现有的 FLAnimatedImage 框架,该框架已被 Facebook、Instagram、Slack 和 Telegram 等许多流行应用程序使用。
使用自定义GIFView
,我们只需要 SwiftUI 中的一行代码就可以在我们的应用程序中显示惊人的 GIF!玩得开心实验和编码!动画 GIF 只是增强 iOS 应用的 UX 和 UI的众多方法之一。
来源:https ://blog.logrocket.com/adding-gifs-ios-app-flanitatedimage-swiftui/
1626088193
iOS app development in Singapore
iOS has become the first priority for most smartphone users because of the security it offers compares to the Android operating system. Due to this reason, it is suggested to launch an app in iOS before other platforms.
Want to develop an iOS app in Singapore?
WebClues Infotech with its worldwide reach has already offered its iOS app development services to customers in Singapore. With a highly-skilled development team of 120+ members, WebClues Infotech has got the required resources an agency needs to fulfil client requirements around the world.
Want to know more about our iOS app development services in Singapore?
Visit: https://www.webcluesinfotech.com/iphone-app-development/
Share your requirements https://www.webcluesinfotech.com/contact-us/
View Portfolio https://www.webcluesinfotech.com/portfolio/
#ios app development in singapore #ios app development company #ios app development #ios #ios app #hire ios developer
1626088709
iOS App Development in the United Arab Emirates
Developed and Developing nations have seen a rapid rise in the demand for iOS app development and the United Arab Emirates is no exception. The use of on-demand apps has increased drastically in the last decade and business is leveraging this demand with launching iOS mobile apps.
Want to develop the iOS app in the United Arab Emirates?
WebClues Infotech after serving multiple clients in UAE has become well aware of the people’s needs in the region. With a highly experienced development team that has completed more than 950+ projects, we are prepared to serve you with your iOS app development needs.
Want to know more about our iOS App Development Services in UAE?
Visit: https://www.webcluesinfotech.com/iphone-app-development/
Share your requirements https://www.webcluesinfotech.com/contact-us/
View Portfolio https://www.webcluesinfotech.com/portfolio/
#ios app development in the united arab emirates #ios app development #ios app #ios #ios app development company #hire ios developer
1625742351
iOS App Development Agency in the USA
Whenever a start-up in the USA launch an MVP version of the app they prefer to launch it only for iPhone user because the US has a large market of iPhone users in comparison to Android. The recent phenomenon of Clubhouse is the biggest example.
Want to develop an iOS app in the USA?
With 2 office locations across the USA and 6 worldwide, WebClues Infotech has the experience of serving a huge client base of 600+. After such a satisfied client base, WebClues Infotech is prepared to serve you with and iOS App Development Services in the USA.
Want to know more about our iOS App Development Services in the USA?
Visit: https://www.webcluesinfotech.com/iphone-app-development/
Share your requirements https://www.webcluesinfotech.com/contact-us/
View Portfolio https://www.webcluesinfotech.com/portfolio/
#ios app development agency in the usa #ios app development agency #ios app development #ios app #ios #hire ios app developer
1625914039
iOS app development company in India
India is considered the IT hub of the world because of n number of IT infrastructure development services offering companies. In this whole market iOS app development is the leading service offered by agencies across India
Want to develop the iOS app in India
WebClues Infotech with its head office in India has created a huge presence across the world over time and has served clients in all of the major countries around the world. WebClues Infotech with a highly skilled development team of 120+ members can help you deliver a better result at a reasonable cost.
Want to know more about our iOS app development services in India?
Visit: https://www.webcluesinfotech.com/iphone-app-development/
Share your requirements https://www.webcluesinfotech.com/contact-us/
View Portfolio https://www.webcluesinfotech.com/portfolio/
#ios app development company in india #ios app development company #ios app development #ios app #ios #hire ios app developer