ios - 在数据源中隐藏 tableviewcell 或过滤器更好吗? (性能问题)

标签 ios swift uitableview

我有一个 UITableViewController,其中有我想隐藏的单元格。

我目前正在做的是隐藏 heightForRowAt 返回 0 的单元格,cellForRowAt 返回 isHidden = false 的单元格。但是由于我使用的是这个解决方案,我注意到当我在我的 tableView 中滚动时应用程序变慢了。

// Currently returning a height of 0 for hidden cells
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if let post = timeline?.postObjects?[indexPath.row], post.hidden ?? false {
        return 0.0
    }
    return UITableView.automaticDimension
}

// And a cell with cell.isHidden = false (corresponding to identifier "hiddenCell")
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if let post = timeline?.postObjects?[indexPath.row] {
        if post.hidden ?? false {
            return tableView.dequeueReusableCell(withIdentifier: "hiddenCell", for: indexPath)
        } else {
            return (tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! PostTableViewCell).with(post: post, timelineController: self, darkMode: isDarkMode())
        }
    }
}

我在想为什么不在数组上应用过滤器以完全删除 tableView 的隐藏单元格,但我不知道每次过滤它们是否对性能有好处......

// Returning only the number of visible cells
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return timeline?.postObjects?.filter{!($0.hidden ?? false)}.count
}

// And creating cells for only visible rows
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if let post = timeline?.postObjects?.filter{!($0.hidden ?? false)}[indexPath.row] {
        return (tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! PostTableViewCell).with(post: post, timelineController: self, darkMode: isDarkMode())
    }
}

什么是最好的选择?在生成单元格时隐藏单元格(第一次)或将它们从列表中排除(第二次)?

最佳答案

我建议让 TableView 数据源方法处理 timelinefiltered 版本。但是,不要在 cellForRowAt 方法中执行此操作,因为我们需要执行一次而不是对每个单元格绘图执行此操作。

因此,您可以做的是声明 filteredTimeline 并在 viewDidLoad 方法中执行一次过滤器(例如):

class TableViewController: UIViewController {
    // ...
    var filteredTimeline // as the same type of `timeline`


    override func viewDidLoad() {
        // ...

        filteredTimeline = timeline?.postObjects?.filter{!($0.hidden ?? false)}

        // ...
    }

    // Returning only the number of visible cells
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return filteredTimeline.count ?? 0
    }

    // And creating cells for only visible rows
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let post = filteredTimeline?.postObjects?.filter{!($0.hidden ?? false)}[indexPath.row] {
            return (tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! PostTableViewCell).with(post: post, timelineController: self, darkMode: isDarkMode())
        }
    }

    // ...
}

如果有更好的地方 filteredTimeline = timeline?.postObjects?.filter{!($0.hidden ?? false)} 而不是 viewDidLoad,您可能需要调用 tableView.reloadData()

您可以做的替代方案:

如果您认为您不需要原始的时间线,您可以自己过滤它:

timeline = timeline?.postObjects?.filter{!($0.hidden ?? false)}
tableView.reloadData()

并且您将不需要额外的过滤数组。


额外提示:

如果在 heightForRowAt 方法中为特定行返回 0.0 值,甚至不会调用 cellForRowAt;例如:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 2
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return indexPath.row == 0 ?? 0.0 : 100.0
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // ...
}

此时,cellForRowAt 应该只被调用一次,因为第一行的高度是 0.0

关于ios - 在数据源中隐藏 tableviewcell 或过滤器更好吗? (性能问题),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54891640/

相关文章:

iphone - 刷新导航 Controller 中的 View

ios - 弹出窗口中的 Swift tableview 不显示数据

ios - Swift中的关联对象,全局键是否实际产生特定实例?

xcode - CGPathAddArc 路径没有出现在带有 Swift 的 SpriteKit 中

ios - 如何将普通搜索栏更改为下图所示的搜索栏

iOS 应用程序在 UIActionSheet 上崩溃

ios - 从 Crashlytics 升级到 Fabric 后无法构建我的应用程序

android - AS3 AIR(ios 和 android)CameraRoll 问题

ios - PickerView无法更改第二行的颜色

ios - 第一个分组 TableView 部分标题未显示