在 iOS Carplay 中延迟加载数据

Posted

技术标签:

【中文标题】在 iOS Carplay 中延迟加载数据【英文标题】:Lazy Loading Data in iOS Carplay 【发布时间】:2019-12-27 14:08:33 【问题描述】:

当用户在 Carplay 中滚动时如何延迟加载项目?

我正在使用 MPPlayableContentDataSource 中的 beginLoadingChildItems 来加载第一组项目,但是当用户滚动到页面底部时如何调用下一页?

【问题讨论】:

我在这里面临另一个问题 - playableContentManager?.reloadData() 永远不会工作。当我将项目添加到列表并调用此函数时,没有任何反应。 关注github.com/pronebird/UIScrollView-InfiniteScroll 【参考方案1】:

您可以在以下函数中实现这一点:

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

,但首先,您需要在以下函数中正确返回项目总数:

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


【讨论】:

您好,感谢您的回复。你能告诉我应该返回什么项目总数,因为可以有无限的项目,以及 indexPath [componentIndex] 中的 componentIndex 是什么?请回复 我想在单个页面中加载 8 个项目,当用户滚动到最后一个项目时加载接下来的 8 个项目 你能检查一下更新后的答案吗,我已经尝试添加一个例子来说明。 感谢您的回答,在我的代码问题中,我们必须将列表中的最后一项声明为容器,然后只调用 beginLoadingChildItems 委托。我的代码中没有。 祝你好运?【参考方案2】:

CarPlay 默认不支持无限滚动。显示列表中的最后一项时没有回调。但是,@amr-el-sayed 的解决方案是一个有趣的解决方案,因为 CarPlay 会在类别首次出现在屏幕上时预加载它们。因此,如果列表中的最后一项是类别,CarPlay 将使用列表中最后一项的索引路径调用beginLoadingChildItemsAtIndexPath,这可用于模拟无限滚动。在这种情况下,有必要调用MPPlayableContentManager reloadData,因为实际上是为嵌套类别(未显示)而不是您尝试实现无限滚动的类别调用预加载。这可能会导致一些闪光,因为 CarPlay 现在必须重绘整个 UI。如果可能,更好的解决方案是最初加载一长串项目。请注意,当 MPPlayableContentManager.contentLimitsEnforced 为真时,CarPlay 将强制限制 enforcedContentItemsCount,例如,当车辆行驶时。

【讨论】:

【参考方案3】:

这里的关键是将您的 MPContentItem 声明为这样的容器

            let item = MPContentItem(identifier: "Tab \(indexPath)")
            item.isContainer = true
            item.isPlayable = false
            return item

只有当该项目在屏幕上可见时,框架才会调用 beginLoadingChildItems 方法。

在 beginLoadingChildItems 内部调用加载更多功能并使用刷新项目

playableContentManager?.reloadData()

功能

【讨论】:

以上是关于在 iOS Carplay 中延迟加载数据的主要内容,如果未能解决你的问题,请参考以下文章

如何延迟加载?

Hibernate延迟加载机制

Hibernate延迟加载

hibernate延迟加载

延迟加载

延迟加载图像在 iPhone 浏览器中不起作用