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

实现按Company的businessName首字母分组的UITableView并隐藏空分组

UITableView按Company名称首字母分组并隐藏空分组问题

我需要创建一个UITableView,根据Company模型的businessName属性首字母进行字母顺序分组显示,同时隐藏没有对应首字母公司的分组。目前已将公司数据获取到控制器中,但无法正确将公司划分到对应分组,也无法隐藏空分组。

当前效果

当前效果
所有字母分组全部显示,且所有公司重复出现在每个分组内。

期望效果

期望效果
仅展示存在对应公司的字母分组,每个分组下只显示首字母匹配的公司。


Company模型

struct Company {
    var uid: String
    var businessAddress: String
    var businessName: String

    init(dictionary: [String : Any]) {
        self.uid = dictionary["uid"] as? String ?? ""
        self.businessAddress = dictionary["businessAddress"] as? String ?? ""
        self.businessName = dictionary["businessName"] as? String ?? ""
    }
}

数据获取Service

struct EmployeeService {
    static func fetchCompanies(completion: @escaping([Company]) -> Void) {
        var companies = [Company]()
        let query = REF_COMPANIES.order(by: "businessName")
        
        query.addSnapshotListener { snapshot, error in
            snapshot?.documentChanges.forEach({ change in
                let dictionary = change.document.data()
                let company = Company(dictionary: dictionary)
                companies.append(company)
                companies.sort {
                    $0.businessName < $1.businessName
                }
                completion(companies)
            })
        }
    }
}

控制器代码

class CompanySelectionController: UIViewController {
    // MARK: - Properties
    var companies = [Company]()
    let sectionTitles = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".map(String.init)
}

// MARK: - UITableViewDataSource
extension CompanySelectionController: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return sectionTitles.count
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return companies.count
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        // Create the header view
        let headerView =  UIView.init(frame: CGRectMake(0, 0, self.view.frame.size.width, 40))
        headerView.backgroundColor = UIColor.groupTableViewBackground
        
        // Create the Label
        let label = UILabel(frame: CGRectMake(10, -40, 120, 60))
        label.font = UIFont(name: "AvenirNext-DemiBold", size: 16)
        label.textAlignment = .left
        label.text = sectionTitles[section]
        
        // Add the label to your headerview
        headerView.addSubview(label)
        
        return headerView
    }
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 5
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifiers.CompanySelectionCell, for: indexPath) as! CompanySelectionCell
        
        cell.selectionStyle = .none
        cell.company = companies[indexPath.row]
        return cell
    }
}

表格Cell代码

protocol CompannyViewModelItem {
    var type: CompannyViewModelItemType { get }
    var rowCount: Int { get }
    var sectionTitle: String { get }
}

class CompanySelectionCell: UITableViewCell {
    // MARK: - Properties
    var company: Company! {
        didSet {
            configure()
        }
    }
    
    private let businessNameLabel: UILabel = {
        let label = UILabel()
        label.font = UIFont(name: "AvenirNext-DemiBold", size: 14)
        label.textColor = .black
        label.textAlignment = .left
        return label
    }()
    
    private let businessAddressLabel: UILabel = {
        let label = UILabel()
        label.font = UIFont(name: "AvenirNext-MediumItalic", size: 12)
        label.textColor = .darkGray
        label.textAlignment = .left
        return label
    }()
    
    lazy var businessStack = UIStackView(arrangedSubviews: [businessNameLabel, businessAddressLabel])
    
    // MARK: - Lifecycle
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - Helper Functions
    fileprivate func configure() {
        guard let company = company else { return }
        let viewModel = CompannyViewModel(company: company)
        
        businessNameLabel.text = viewModel.businessName
        businessAddressLabel.text = viewModel.businessAddress
    }
}

ViewModel枚举

enum CompannyViewModelItemType { 
    case uid 
    case businessName 
}

我尝试修改viewForHeaderInSection中的label属性以匹配正确的首字母,但目前仅达到截图中的效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 15:35:52