在 iOS Carplay 中延迟加载数据
Lazy Loading Data in iOS Carplay
如何在 Carplay 中滚动时延迟加载项目?
我正在使用 MPPlayableContentDataSource 中的 beginLoadingChildItems 来加载第一组项目,但是当用户滚动到页面底部时我如何调用下一页?
您可以在以下函数中实现此目的:
func beginLoadingChildItems(at indexPath: IndexPath, completionHandler: @escaping (Error?) -> Void)
例如:
if (indexPath[componentIndex] + 1) % Threshold == 0 { // Threshold is Your Defined Batch Size
// Load the next corresponding batch
}
加载您的惰性数据,然后调用:
completionHandler(nil) // In case of no error has occurred
,但首先,您需要 return 在以下函数中正确计算项目总数:
func numberOfChildItems(at indexPath: IndexPath) -> Int
类似于下面的内容,
class YourDataSource : MPPlayableContentDataSource {
private var items = [MPContentItem]()
private var currentBatch = 0
func beginLoadingChildItems(at indexPath: IndexPath, completionHandler: @escaping (Error?) -> Void) {
// indexPath[1]: is current list level, as per CarPlay list indexing (It's an array of the indices as ex: indexPath = [0,1] means Index 0 in the first level and index 1 at the second level).
// % 8: Means each 8 items, I will perform the corresponding action.
// currentBatch + 1 == nextBatch, This check in order to ensure that you load the batches in their sequences.
let currentCount = indexPath[1] + 1
let nextBatch = (currentCount / 8) + 1
if currentCount % 8 == 0 && currentBatch + 1 == nextBatch {
// Load the next corresponding batch
YourAPIHandler.asyncCall { newItems in
self.currentBatch = self.currentBatch + 1
items.append(newItems)
completionHandler(nil)
MPPlayableContentManager.shared().reloadData()
}
} else {
completionHandler(nil)
}
}
}
func numberOfChildItems(at indexPath: IndexPath) -> Int {
return self.items.count
}
这里的关键是将您的 MPContentItem 声明为这样的容器
let item = MPContentItem(identifier: "Tab \(indexPath)")
item.isContainer = true
item.isPlayable = false
return item
然后当该项目在屏幕上可见时,只有框架会调用 beginLoadingChildItems 方法。
在 beginLoadingChildItems 中调用加载更多函数并使用
刷新项目
playableContentManager?.reloadData()
函数
CarPlay 默认不支持无限滚动。显示列表中的最后一项时没有回调。然而,@amr-el-sayed 的解决方案很有趣,因为 CarPlay 会在类别首次出现在屏幕上时预加载它们。因此,如果列表中的最后一项是类别,CarPlay 将使用列表中最后一项的索引路径调用 beginLoadingChildItemsAtIndexPath
,这可用于模拟无限滚动。在这种情况下,有必要调用 MPPlayableContentManager reloadData
因为预加载实际上是为嵌套类别(未显示)调用的,而不是您尝试实现无限滚动的类别。这可能会导致一些闪光,因为 CarPlay 现在必须重新绘制整个 UI。如果可能,更好的解决方案是最初加载一长串项目。请注意,CarPlay 将强制执行 enforcedContentItemsCount
when MPPlayableContentManager.contentLimitsEnforced 的限制为真,例如,当车辆在行驶中时。
如何在 Carplay 中滚动时延迟加载项目?
我正在使用 MPPlayableContentDataSource 中的 beginLoadingChildItems 来加载第一组项目,但是当用户滚动到页面底部时我如何调用下一页?
您可以在以下函数中实现此目的:
func beginLoadingChildItems(at indexPath: IndexPath, completionHandler: @escaping (Error?) -> Void)
例如:
if (indexPath[componentIndex] + 1) % Threshold == 0 { // Threshold is Your Defined Batch Size
// Load the next corresponding batch
}
加载您的惰性数据,然后调用:
completionHandler(nil) // In case of no error has occurred
,但首先,您需要 return 在以下函数中正确计算项目总数:
func numberOfChildItems(at indexPath: IndexPath) -> Int
类似于下面的内容,
class YourDataSource : MPPlayableContentDataSource {
private var items = [MPContentItem]()
private var currentBatch = 0
func beginLoadingChildItems(at indexPath: IndexPath, completionHandler: @escaping (Error?) -> Void) {
// indexPath[1]: is current list level, as per CarPlay list indexing (It's an array of the indices as ex: indexPath = [0,1] means Index 0 in the first level and index 1 at the second level).
// % 8: Means each 8 items, I will perform the corresponding action.
// currentBatch + 1 == nextBatch, This check in order to ensure that you load the batches in their sequences.
let currentCount = indexPath[1] + 1
let nextBatch = (currentCount / 8) + 1
if currentCount % 8 == 0 && currentBatch + 1 == nextBatch {
// Load the next corresponding batch
YourAPIHandler.asyncCall { newItems in
self.currentBatch = self.currentBatch + 1
items.append(newItems)
completionHandler(nil)
MPPlayableContentManager.shared().reloadData()
}
} else {
completionHandler(nil)
}
}
}
func numberOfChildItems(at indexPath: IndexPath) -> Int {
return self.items.count
}
这里的关键是将您的 MPContentItem 声明为这样的容器
let item = MPContentItem(identifier: "Tab \(indexPath)")
item.isContainer = true
item.isPlayable = false
return item
然后当该项目在屏幕上可见时,只有框架会调用 beginLoadingChildItems 方法。
在 beginLoadingChildItems 中调用加载更多函数并使用
刷新项目playableContentManager?.reloadData()
函数
CarPlay 默认不支持无限滚动。显示列表中的最后一项时没有回调。然而,@amr-el-sayed 的解决方案很有趣,因为 CarPlay 会在类别首次出现在屏幕上时预加载它们。因此,如果列表中的最后一项是类别,CarPlay 将使用列表中最后一项的索引路径调用 beginLoadingChildItemsAtIndexPath
,这可用于模拟无限滚动。在这种情况下,有必要调用 MPPlayableContentManager reloadData
因为预加载实际上是为嵌套类别(未显示)调用的,而不是您尝试实现无限滚动的类别。这可能会导致一些闪光,因为 CarPlay 现在必须重新绘制整个 UI。如果可能,更好的解决方案是最初加载一长串项目。请注意,CarPlay 将强制执行 enforcedContentItemsCount
when MPPlayableContentManager.contentLimitsEnforced 的限制为真,例如,当车辆在行驶中时。