我正在尝试使用 Kingfisher
SDK 显示远程图像,图像已加载但未显示
import SwiftUI
import Kingfisher
struct Tab_Home: View {
//Slider
@State var sliderIndex:Int = 0
//Search bar
@State var search:String = ""
@ObservedObject var API = REST_API()
var body: some View {
VStack{
ZStack{
Group{
Rectangle().foregroundColor(Color.white.opacity(0.1))
.cornerRadius(22.5)
HStack(spacing : 0){
Image(systemName: "magnifyingglass")
.resizable()
.frame(width : 20 , height : 20)
.aspectRatio(contentMode: .fit)
.foregroundColor(Color.white)
.padding(.leading , 10)
TextFieldPro(placeholder : Text("Search").foregroundColor(.white), text: $search)
.padding(.leading , 10)
.padding(.trailing , 15)
.frame( height : 45)
.foregroundColor(Color.white)
}
}.padding(.leading , 10)
.padding(.trailing , 10)
.padding(.bottom , 5)
.padding(.top , 15)
}.frame(height : 65)
.background(Color(hex: "#CC2323"))
Spacer()
ScrollView{
TabView(selection : $sliderIndex){
ForEach(Env.sharedInstance.settings.sliders , id : \.self){ slider in
SliderBite( data: slider).frame(width :UIScreen.main.bounds.width )
}
} .tabViewStyle(PageTabViewStyle())
}
.padding(.top , 10)
.onAppear(){
API.checkin()
}
}
}
}
struct Tab_Home_Previews: PreviewProvider {
static var previews: some View {
Tab_Home()
}
}
struct SliderBite: View {
let data:DTO_SLIDER
var body: some View {
Group{
if data.full_image != nil {
KFImage(URL(string: data.full_image!)!)
.fade(duration: 0.25)
.onProgress { receivedSize, totalSize in }
.onSuccess { _ in print("Image loaded") }
.onFailure { error in print("Load image error : \(error)") }
.frame(width :UIScreen.main.bounds.width , height : 200)
.aspectRatio(contentMode: .fill)
.background(Color.black)
}
}.clipped()
}
}
//Decoded from rest API
struct DTO_SLIDER:Decodable,Hashable{
var full_image:String?
}
我错过了什么?
答案 0 :(得分:1)
问题不在于 KFImage,它按预期加载,但事实上 TabView 不知何故不知道图像已加载并且需要重新渲染它,但可以轻松解决:>
存储您的 url 以显示在一个数组中,然后在 TabView 中使用 ForEach - 这足以使图像在加载后显示:
struct TabHome: View {
@State var search: String = ""
let urls = [
"https://www.broadway.org.uk/sites/default/files/styles/banner_crop/public/2019-10/star-wars-the-rise-of-skywalker-banner-min.jpg?h=639d4ef1&itok=z4KZ-3Tt",
"https://www.broadway.org.uk/sites/default/files/styles/banner_crop/public/2019-11/star-wars-quiz-banner-min.jpg?h=f75da074&itok=bFe6rBe_"]
var body: some View {
VStack(spacing : 15) {
HStack(spacing : 10) {
Image(systemName: "magnifyingglass")
.resizable()
.frame(width: 20, height: 20)
TextField("Search", text: $search)
.frame(height: 45)
}
.padding(.horizontal)
.background(
RoundedRectangle(cornerRadius: 22.5)
.foregroundColor(Color.gray.opacity(0.1))
)
.padding()
ScrollView{
TabView {
ForEach(urls, id: \.self) { url in
SliderBite(url: url)
}
} .tabViewStyle(PageTabViewStyle())
}
}
}
}
您可能还想调整 KFImage 的大小:
struct SliderBite: View {
let url: String
var body: some View {
KFImage(URL(string: url)!)
.resizable()
.fade(duration: 0.25)
.aspectRatio(contentMode: .fill)
.frame(height : 200)
.background(Color.black)
}
}
解决显示来自相同网址的图片
如果你像这样声明 DTO_SLIDER:
struct DTO_SLIDER: Decodable, Identifiable {
let full_image: String?
let id = UUID()
}
它会确保每一个都是独一无二的,即使它有相同的 full_image。 这也意味着您可以这样使用它:
ForEach(Env.sharedInstance.settings.sliders) { slider in
//...
}