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

iOS Swift11 UITableView自定义单元格显示空白问题

问题描述

Swift开发初学者,运行代码时期望实现效果:

  • 单元格内展示邮箱地址
  • 单元格右侧显示Detail disclosure指示器
    实际运行后仅显示空白单元格。

项目相关配置与代码

Main.storyboard

Main.storyboard配置界面
运行后空白单元格效果

AddressBookTableViewController.swift

import UIKit

class AddressBookTableViewController: UITableViewController {
    let dataSource = ContactEmailDataSource()
    override func viewDidLoad() {
        super.viewDidLoad()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem
    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataSource.countOfEmails()
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ContactCell", for: indexPath)
        let cellContact = dataSource.emailAtIndex(index: indexPath.row)
        cell.textLabel?.text = cellContact.emailAddress
        return cell
    }
    

    /*
    // Override to support conditional editing of the table view.
    override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        // Return false if you do not want the specified item to be editable.
        return true
    }
    */

    /*
    // Override to support editing the table view.
    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            // Delete the row from the data source
            tableView.deleteRows(at: [indexPath], with: .fade)
        } else if editingStyle == .insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }
    }
    */

    /*
    // Override to support rearranging the table view.
    override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {

    }
    */

    /*
    // Override to support conditional rearranging of the table view.
    override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
        // Return false if you do not want the item to be re-orderable.
        return true
    }
    */

    /*
    // MARK: - Navigation
    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */
}

ContactEmail.swift

import UIKit

class ContactEmail: NSObject {
    var emailAddress: String
    
    override init () {
        emailAddress = "example@email.com"
        super.init()
    }
    
    init(emailAddress email: String) {
        emailAddress = email
        super.init()
    }
}

ContactEmailDataSource.swift

import UIKit

class ContactEmailDataSource: NSObject {
    let emailAddresses = NSMutableArray()
    
    override init() {
        super.init()
        loadEmailAddresses()
    }
    func loadEmailAddresses() {
        let sample1 = ContactEmail()
        emailAddresses.add(sample1)
        let sample2 = ContactEmail(emailAddress: "example@example.com")
        addEmail(contact: sample2)
    }
    func addEmail(contact c: ContactEmail) {
        emailAddresses.add(c)
    }
    func countOfEmails() -> Int {
        return emailAddresses.count
    }
    func emailAtIndex(index i: Int) -> ContactEmail {
        return emailAddresses.object(at: i) as! ContactEmail
    }
}

问题原因与修复方案

代码层面的数据源计数、取值、赋值逻辑没有语法错误,空白单元格和附件不显示是Storyboard配置错误导致的,常见原因和对应修复操作如下:

  1. 单元格重用标识不匹配:选中TableView下的Prototype Cell,在右侧属性检查器中确认Identifier字段准确填写ContactCell,不要有多余空格、大小写错误。
  2. 单元格样式设置错误:如果Cell的Style选成了Custom,系统不会自动创建默认的textLabel控件,给cell.textLabel?.text赋值不会有任何效果,把Style改成Basic即可正常加载默认文本标签。如果需要自定义单元格样式,不要依赖系统默认的textLabel,要手动拖入UILabel控件并绑定自定义输出口赋值。
  3. 附件类型未配置:在Cell的属性检查器中找到Accessory下拉菜单,选择Detail Disclosure,即可在单元格右侧显示要求的指示器。

如果操作后仍然空白,可以在cellForRowAt方法中加入调试代码print(cellContact.emailAddress, cell.textLabel),如果控制台能正常打印出邮箱地址但textLabel显示为nil,即可确认是单元格样式配置问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 20:39:19