Swift 4中如何过滤UITableViewCell,仅显示登录用户所属记录
解决Swift 4中UITableView仅显示当前登录用户记录的问题
嘿,我来帮你捋清楚这个问题的正确解法!你可能一开始想错了方向——千万别在cellForRowAt方法里做条件判断来跳过单元格,因为这个方法的职责是配置已经确定要展示的单元格,硬在这里过滤会导致表格行数和实际要显示的内容不匹配,要么出现空白单元格,要么直接触发索引越界错误。
正确的做法是先把数据源过滤好,只保留当前登录用户的记录,再让TableView基于这个过滤后的数组工作,具体步骤如下:
1. 准备过滤后的数据源
假设你原本有一个包含所有用户记录的数组(比如叫allRuns),每个记录模型(比如Run)有一个userId属性用来标识所属用户,同时你已经拿到了当前登录用户的ID(比如currentUserId)。那你可以创建一个专门的数组来存储当前用户的记录:
// 定义全局或类级别的过滤后数据源 var currentUserRuns: [Run] = [] // 在合适的时机(比如登录成功后、获取到所有记录后)执行过滤 func filterCurrentUserRuns() { // 假设currentUserId是当前登录用户的唯一标识 guard let currentUserId = AuthManager.shared.currentUserId else { currentUserRuns = [] return } // 只保留userId和当前用户ID匹配的记录 currentUserRuns = allRuns.filter { $0.userId == currentUserId } // 刷新表格 tableView.reloadData() }
2. 告诉TableView要显示的行数
在numberOfRowsInSection方法里,直接返回过滤后数组的长度,这样TableView就只会创建对应数量的单元格:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return currentUserRuns.count }
3. 配置单元格
现在在cellForRowAt里,直接从过滤后的数组取数据配置单元格就好,完全不用再做条件判断:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard let cell = tableView.dequeueReusableCell(withIdentifier: "RunCell", for: indexPath) as? RunCell else { // 如果获取失败,返回一个默认单元格 return UITableViewCell(style: .default, reuseIdentifier: nil) } // 从过滤后的数组取出当前行的记录 let userRun = currentUserRuns[indexPath.row] // 这里根据你的需求配置单元格内容,比如: cell.runDistanceLabel.text = "\(userRun.distance) km" cell.runDateLabel.text = userRun.date.formatted() return cell }
补充说明
- 当数据源发生变化(比如新增了记录、用户切换登录状态),记得重新调用
filterCurrentUserRuns()方法,这样表格会自动刷新显示最新的符合条件的记录。 - 这种方式比在
cellForRowAt里判断要高效得多,因为过滤只执行一次(或在需要时执行),而不是每次创建单元格都做判断。
内容的提问来源于stack exchange,提问作者Luke Varty
相关产品推荐
相关产品推荐

