Swift动态UITableView如何删除行?删除后出现空白行
解决UITableView显示符合通讯录条件用户时出现空白行的问题
嘿,我来帮你搞定这个问题!你现在的做法是在cellForRowAt方法里判断用户是否在通讯录中,然后尝试删除不符合条件的行,但这种方式其实踩了UITableView数据源逻辑的坑——这也是为什么会出现空白行的原因。
问题根源分析
- 你的
numberOfRowsInSection仍然返回原始users数组的长度,哪怕你删除了某一行,数据源的长度没更新,TableView还是会渲染对应数量的cell,那些被你“跳过”的位置就会变成空白行。 - 在
cellForRowAt里调用deleteRows和reloadData是非常危险的,会触发TableView的重新布局,很容易造成循环调用或者布局异常。
正确解决方案:提前过滤数据源
正确的思路应该是提前筛选出符合条件的用户,而不是在渲染cell的时候临时处理。具体步骤如下:
- 定义一个新数组存储符合条件的用户
// 假设你的用户模型是User类型,在类里添加这个属性 var filteredUsers: [User] = []
- 在合适的时机(比如视图加载完成、通讯录数据更新时)执行过滤逻辑
// 调用你的通讯录查询方法,过滤出电话号码存在的用户 filteredUsers = users.filter { user in guard let phoneNumber = user.phoneNumber else { // 没有电话号码的直接排除 return false } return searchForContactUsingPhoneNumber(phoneNumber: phoneNumber) } // 过滤完成后刷新TableView tableView.reloadData()
- 修改TableView的数据源方法,使用过滤后的数组
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // 返回过滤后数组的长度,这样TableView只会渲染符合条件的行数 return filteredUsers.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! UserCell let user = filteredUsers[indexPath.row] // 直接配置cell即可,不需要再判断是否在通讯录中 cell.textLabel?.text = user.name cell.detailTextLabel?.text = user.phoneNumber cell.backgroundColor = UIColor(r: 35, g: 35, b: 35) cell.textLabel?.textColor = UIColor.white cell.detailTextLabel?.textColor = UIColor.white if let profileImageUrl = user.profileImageUrl { cell.profileImageView.loadImageUsingCacheWithUrlString(profileImageUrl) } else { // 如果没有头像,建议设置默认图,而不是删除行 cell.profileImageView.image = UIImage(named: "default-avatar") } return cell }
额外优化:处理通讯录动态变化
如果用户在App运行过程中修改了通讯录(比如添加/删除联系人),可以在viewWillAppear里重新执行过滤逻辑,保证数据实时更新:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // 重新过滤数据并刷新 filteredUsers = users.filter { user in guard let phoneNumber = user.phoneNumber else { return false } return searchForContactUsingPhoneNumber(phoneNumber: phoneNumber) } tableView.reloadData() }
内容的提问来源于stack exchange,提问作者Danil Onishenko
相关产品推荐
相关产品推荐

