我有一个由多个频道组成的流媒体应用程序,每个频道都有DVR。在主页上,所有频道均按照类别显示在行中。当用户单击某个频道项目时,它会转到一个详细页面,该页面在水平滚动行中包含DVR。所有通道和DVR项都有图像,我正在使用URLImage(https://github.com/dmytro-anokhin/url-image)库从URL加载图像。问题是当我运行该应用程序时,通道图像从右下到左上(从最后一项到第一项)加载。当我单击频道并导航到详细屏幕时,DVR的图像从右到左开始加载,即从最后一项到第一项。这就造成了一个问题,因为通道的DVR数据太多,并且加载所有图像需要5秒钟。如果它开始从第一项开始加载图像,那就太好了,因此即使花费5秒钟,用户也不会意识到并生效。
我不明白为什么这样做。有解决此问题的解决方案吗?我怎样才能迫使它从第一个项目开始加载到最后一个项目。这是我的代码,用于在其中显示DVR:
ForEach(1..<chan.getDVR().count, id: \.self){index in
Button(action:
{
self.str = self.chan.getDVR()[index].getHlsStreamURL()
self.refresh = false
self.ind = index
}) {
dvrItem(DVRItem: self.chan.getDVR()[index])
.buttonStyle(PlainButtonStyle())
.padding(.trailing,3)
.cornerRadius(7)
}.buttonStyle(PlainButtonStyle())
}
和dvrItem:
struct dvrItem: View {
var DVRItem: dvr
var body: some View {
VStack( alignment: .leading) {
URLImage(URL(string: DVRItem.getLogoUrlHD().replacingOccurrences(of: "http", with: "https", options: .literal, range: nil))!, placeholder: { _ in Image("nologo").resizable().aspectRatio(contentMode: .fill).clipped() } ){
proxy in
proxy.image
.resizable() // Make image resizable
.aspectRatio(contentMode: .fill) // Fill the frame
.clipped() // Clip overlaping parts
}
.frame(width: 198, height: 114)
.cornerRadius(7)
.padding(.leading, 10)
.padding(.top, 5)
Text(self.DVRItem.getName())
.foregroundColor(Color.white)
.padding(.leading, 5)
.padding(.trailing, 5)
Text(self.DVRItem.getDescription())
.foregroundColor(Color(red: 80.0/150, green: 80.0/150, blue: 80.0/150))
.lineLimit(nil)
.padding(.leading, 5)
.padding(.trailing, 5)
Spacer()
.frame(height: 5)
}
}
}
struct dvrItem_Previews: PreviewProvider {
static var previews: some View {
dvrItem(DVRItem: channels[0].getDVR()[0])
}
}
我要怎么做?顺便说一下,我尝试仅加载前10个DVR项,例如ForEach(1..<10, id: \.self){index in
,但它给运行时带来了错误。
答案 0 :(得分:0)
尝试了许多事情后,我使用URLImage Library的选项解决了该问题。
URLImages具有一个延迟选项,可用于延迟图像加载过程。用法如下:
URLImage(URL(string: DVRItem.getLogoUrlHD().replacingOccurrences(of: "http", with: "https", options: .literal, range: nil))!, delay: 0.25, placeholder: { _ in Image("nologo").resizable().aspectRatio(contentMode: .fill).clipped() } ){
proxy in
proxy.image
.resizable() // Make image resizable
.aspectRatio(contentMode: .fill) // Fill the frame
.clipped() // Clip overlaping parts
}
我更新了DVRItem并添加了一个名为index的新变量:
var ind: Int
并使用该变量无延迟地加载前5个元素,以0.15延迟加载后15个元素,并以0.25延迟加载其余元素。这样,它将立即加载前5个元素,然后加载其余元素。我的最终代码如下:
struct dvrItem: View {
var DVRItem: dvr
var ind: Int
var body: some View {
VStack( alignment: .leading) {
URLImage(URL(string: DVRItem.getLogoUrlHD().replacingOccurrences(of: "http", with: "https", options: .literal, range: nil))!, delay: (self.ind < 5) ? 0 : (self.ind < 20 ? 0.15 : 0.25), placeholder: { _ in Image("nologo").resizable().aspectRatio(contentMode: .fill).clipped() } ){
proxy in
proxy.image
.resizable() // Make image resizable
.aspectRatio(contentMode: .fill) // Fill the frame
.clipped() // Clip overlaping parts
}
.frame(width: 198, height: 114)
.cornerRadius(7)
.padding(.leading, 10)
.padding(.top, 5)
Text(self.DVRItem.getName())
.foregroundColor(Color.white)
.padding(.leading, 5)
.padding(.trailing, 5)
Text(self.DVRItem.getDescription())
.foregroundColor(Color(red: 80.0/150, green: 80.0/150, blue: 80.0/150))
.lineLimit(nil)
.padding(.leading, 5)
.padding(.trailing, 5)
Spacer()
.frame(height: 5)
}
}
}
struct dvrItem_Previews: PreviewProvider {
static var previews: some View {
dvrItem(DVRItem: channels[0].getDVR()[0], ind: 0)
}
}
然后按如下所示调用DVRItem并为ind分配索引值:
ForEach(1..<chan.getDVR().count, id: \.self){index in
Button(action:
{
self.str = self.chan.getDVR()[index].getHlsStreamURL()
self.refresh = false
self.ind = index
}) {
dvrItem(DVRItem: self.chan.getDVR()[index], ind: index)
.buttonStyle(PlainButtonStyle())
.padding(.trailing,3)
.cornerRadius(7)
}.buttonStyle(PlainButtonStyle())
}
我仍然不知道为什么它从上一个项目开始加载,但这解决了我的问题。我尝试了类似本文In SwiftUI, where are the control events, i.e. scrollViewDidScroll to detect the bottom of list data的类似解决方案,但是它们不适用于水平滚动。