You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift加载Realm数据时UITableView出现重复分区如何解决

问题原因

出现同首字母重复分区、每个分区仅1行数据的核心问题出在数据加载逻辑:

  • loadArtists() 从Realm读取数据时,没有走首字母分组流程,直接把每个联系人包装为单元素数组追加到contactsArray,直接导致每个联系人单独占一个分区
  • 原分组逻辑没有做首字母归一化处理,中文联系人、大小写不同的英文同首字母联系人无法被分到同一组
  • 数组操作前没有清空旧数据,多次加载会出现数据重复叠加
修复步骤
  1. 重写loadArtists()方法,读取Realm数据后先存入contacts数组,再统一调用分组逻辑:
func loadArtists(){
    // 清空旧数据避免重复
    contacts.removeAll()
    contactsArray.removeAll()
    
    let contactsRealm = realm.objects(ContactRealm.self)
    for contact in contactsRealm {
        guard let name = contact.artistName,
              let number = contact.artistPhoneNumber else { continue }
        contacts.append(Contact(name: name, number: number))
    }
    // 全量数据拉取完成后执行分组
    setupContacts()
    tableView.reloadData()
}
  1. 优化setupContacts()分组逻辑,增加中文转拼音、首字母大写统一处理,对齐系统通讯录分组规则:
func setupContacts() {
    contactsArray.removeAll()
    
    let groupedContacts = Dictionary(grouping: contacts) { contact -> Character in
        // 中文转拼音、去除音标、统一大写
        let nameRef = NSMutableString(string: contact.name) as CFMutableString
        CFStringTransform(nameRef, nil, kCFStringTransformToLatin, false)
        CFStringTransform(nameRef, nil, kCFStringTransformStripDiacritics, false)
        let normalizedStr = (nameRef as String).uppercased()
        // 无效首字母归入#分组
        return normalizedStr.first ?? "#"
    }
    
    // 排序:A-Z在前,#分组在最后
    let sortedKeys = groupedContacts.keys.sorted { c1, c2 in
        if c1 == "#" { return false }
        if c2 == "#" { return true }
        return c1 < c2
    }
    
    sortedKeys.forEach { key in
        // 分组内联系人按姓名排序
        let sortedGroupContacts = groupedContacts[key]!.sorted { $0.name < $1.name }
        contactsArray.append(sortedGroupContacts)
    }
}
  1. 简化新增联系人的回调逻辑,上传完成后直接重新拉取全量数据即可,不需要手动维护数组:
@IBAction func goToContacts(segue: UIStoryboardSegue) {
    guard let addVC = segue.source as? AddArtistViewController,
          let name = addVC.name.text,
          let phoneNumber = addVC.phoneNumber.text else { return }
    
    uploadContacts(contactName: name, contactNumber: phoneNumber)
    loadArtists()
}
修复后效果
  • 同首字母(支持中文拼音匹配、英文大小写兼容)的联系人自动归入同一分区
  • 分区按A-Z顺序排列,无法识别首字母的联系人归入末尾#分区
  • 每个分区内联系人按姓名排序,完全对齐系统原生通讯录的分组体验

问题效果截图

内容的提问来源于stack exchange,提问作者senanindigo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 03:24:18