如何将图像更改为结构?斯威夫特用户界面
How to change an image to a structure? SwiftUI
现在,当应用程序打开时,会显示来自 link 的图像,但如果用户没有互联网,则会显示来自我的应用程序文件的图像
如何代替我的图像 - 名称:“noconnection”,显示我的结构:Indicator() 如果用户没有互联网连接。
我的代码:
struct RemoteImage: View {
private enum LoadState {
case loading, success, failure
}
private class Loader: ObservableObject {
var data = Data()
var state = LoadState.loading
init(url: String) {
guard let parsedURL = URL(string: url) else {
fatalError("Invalid URL: \(url)")
}
URLSession.shared.dataTask(with: parsedURL) { data, response, error in
if let data = data, data.count > 0 {
self.data = data
self.state = .success
} else {
self.state = .failure
}
DispatchQueue.main.async {
self.objectWillChange.send()
}
}.resume()
}
}
@StateObject private var loader: Loader
var loading: Image
var failure: Image
var body: some View {
selectImage()
.resizable()
}
init(url: String, loading: Image = Image("loadingimage"), failure: Image = Image("noconnection")) {
_loader = StateObject(wrappedValue: Loader(url: url))
self.loading = loading
self.failure = failure
}
private func selectImage() -> Image {
switch loader.state {
case .loading:
return loading
case .failure:
return failure
default:
if let image = UIImage(data: loader.data) {
return Image(uiImage: image).resizable()
} else {
return failure
}
}
}
}
我的结构 - Indicator() - 代码
struct Indicator : UIViewRepresentable {
func makeUIView(context: Context) -> UIActivityIndicatorView {
let indicator = UIActivityIndicatorView()
indicator.startAnimating()
indicator.style = .large
indicator.color = .systemTeal
return indicator
}
func updateUIView(_ uiView: UIActivityIndicatorView, context: Context) {
//
}
}
应显示此结构 - Indicator() - 而不是图像“noconnection”
如有任何帮助,我将不胜感激
您可以更改 failure
类型以接受 Indicator
。然后,将 selectImage
更改为 @ViewBuilder
returns some View
:
struct RemoteImage: View {
private enum LoadState {
case loading, success, failure
}
private class Loader: ObservableObject {
var data = Data()
var state = LoadState.loading
init(url: String) {
guard let parsedURL = URL(string: url) else {
fatalError("Invalid URL: \(url)")
}
URLSession.shared.dataTask(with: parsedURL) { data, response, error in
if let data = data, data.count > 0 {
self.data = data
self.state = .success
} else {
self.state = .failure
}
DispatchQueue.main.async {
self.objectWillChange.send()
}
}.resume()
}
}
@StateObject private var loader: Loader
var loading: Image
var failure: Indicator
var body: some View {
selectImage()
}
init(url: String, loading: Image = Image("loadingimage").resizable(), failure: Indicator = Indicator()) {
_loader = StateObject(wrappedValue: Loader(url: url))
self.loading = loading
self.failure = failure
}
@ViewBuilder private func selectImage() -> some View {
switch loader.state {
case .loading:
loading
case .failure:
failure
default:
if let image = UIImage(data: loader.data) {
Image(uiImage: image).resizable()
} else {
failure
}
}
}
}
在这种情况下,您可能希望摆脱默认参数并设置 var failure = Indicator()
而不是使用初始化程序
现在,当应用程序打开时,会显示来自 link 的图像,但如果用户没有互联网,则会显示来自我的应用程序文件的图像
如何代替我的图像 - 名称:“noconnection”,显示我的结构:Indicator() 如果用户没有互联网连接。
我的代码:
struct RemoteImage: View {
private enum LoadState {
case loading, success, failure
}
private class Loader: ObservableObject {
var data = Data()
var state = LoadState.loading
init(url: String) {
guard let parsedURL = URL(string: url) else {
fatalError("Invalid URL: \(url)")
}
URLSession.shared.dataTask(with: parsedURL) { data, response, error in
if let data = data, data.count > 0 {
self.data = data
self.state = .success
} else {
self.state = .failure
}
DispatchQueue.main.async {
self.objectWillChange.send()
}
}.resume()
}
}
@StateObject private var loader: Loader
var loading: Image
var failure: Image
var body: some View {
selectImage()
.resizable()
}
init(url: String, loading: Image = Image("loadingimage"), failure: Image = Image("noconnection")) {
_loader = StateObject(wrappedValue: Loader(url: url))
self.loading = loading
self.failure = failure
}
private func selectImage() -> Image {
switch loader.state {
case .loading:
return loading
case .failure:
return failure
default:
if let image = UIImage(data: loader.data) {
return Image(uiImage: image).resizable()
} else {
return failure
}
}
}
}
我的结构 - Indicator() - 代码
struct Indicator : UIViewRepresentable {
func makeUIView(context: Context) -> UIActivityIndicatorView {
let indicator = UIActivityIndicatorView()
indicator.startAnimating()
indicator.style = .large
indicator.color = .systemTeal
return indicator
}
func updateUIView(_ uiView: UIActivityIndicatorView, context: Context) {
//
}
}
应显示此结构 - Indicator() - 而不是图像“noconnection”
如有任何帮助,我将不胜感激
您可以更改 failure
类型以接受 Indicator
。然后,将 selectImage
更改为 @ViewBuilder
returns some View
:
struct RemoteImage: View {
private enum LoadState {
case loading, success, failure
}
private class Loader: ObservableObject {
var data = Data()
var state = LoadState.loading
init(url: String) {
guard let parsedURL = URL(string: url) else {
fatalError("Invalid URL: \(url)")
}
URLSession.shared.dataTask(with: parsedURL) { data, response, error in
if let data = data, data.count > 0 {
self.data = data
self.state = .success
} else {
self.state = .failure
}
DispatchQueue.main.async {
self.objectWillChange.send()
}
}.resume()
}
}
@StateObject private var loader: Loader
var loading: Image
var failure: Indicator
var body: some View {
selectImage()
}
init(url: String, loading: Image = Image("loadingimage").resizable(), failure: Indicator = Indicator()) {
_loader = StateObject(wrappedValue: Loader(url: url))
self.loading = loading
self.failure = failure
}
@ViewBuilder private func selectImage() -> some View {
switch loader.state {
case .loading:
loading
case .failure:
failure
default:
if let image = UIImage(data: loader.data) {
Image(uiImage: image).resizable()
} else {
failure
}
}
}
}
在这种情况下,您可能希望摆脱默认参数并设置 var failure = Indicator()
而不是使用初始化程序