自定义 TableViewCell 中的标签始终返回其初始化值

Posted

技术标签:

【中文标题】自定义 TableViewCell 中的标签始终返回其初始化值【英文标题】:Labels in custom TableViewCell always return their initialization values 【发布时间】:2018-01-30 06:59:15 【问题描述】:

我对 Swift 还很陌生,并且对以下问题进行了广泛的研究但没有成功。

我创建了一个名为 ConversationCell 的自定义 TableViewCell 类,并在 NIB/XIB 文件中定义了它的 UI。

 import UIKit
    import SwipeCellKit

    class ConversationCell: SwipeTableViewCell 

        @IBOutlet weak var distanceLabel: UILabel!
        @IBOutlet weak var locationLabel: UILabel!
        @IBOutlet weak var subjectLabel: UILabel!
        @IBOutlet weak var bodyLabel: UILabel!
        @IBOutlet weak var profileImageView: UIImageView!
        @IBOutlet weak var usernameLabel: UILabel!
        @IBOutlet weak var starImageView: UIImageView!
        @IBOutlet weak var dateLabel: UILabel!

        var isFollowed = false

        override func awakeFromNib() 
            super.awakeFromNib()
            // Initialization code
        
    

然后我编写了一个名为Conversation 的简单类,它是ConversationCell 的模型类。

class Conversation 
    var distance = "123 ft."
    var location = "123 Market St"
    var date = "Yesterday, 10:45AM"
    var subject = "Default subject."
    var body = "Default body"


   // var subject = "My Subject"
    //var body = "My Body"

    var username = "worldsurfer"
    var profilePhoto = UIImage(named: "profilePhoto")

最后,我在我的类HomeTabViewController 中添加了一个使用自定义ConversationCellTableView,它是一个既充当TableView 的源又充当委托的ViewController。

请看下面的代码,我在func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)内的单元格中打印标签的内容。

而不是返回我在初始化对话数组时定义的标签值(即“1st Conversation”、“2nd Conversation”、“3rd Conversation” - 在运行时在 TableView 中正确显示),它返回NIB 文件中定义的默认标签文本值(即,“我们面前的可观确实是崇高的。”)。

import UIKit
import SwipeCellKit

class HomeTabViewController: CoreDesignViewController 
    @IBOutlet weak var tableView: UITableView!

    var conversationArray : [Conversation] = []

    override func viewDidLoad() 
        super.viewDidLoad()

        tableView.register(UINib(nibName: "ConversationCell", bundle: nil), forCellReuseIdentifier: "homeTabCell")

        tableView.dataSource = self
        tableView.delegate = self


        let conversation1 = Conversation()
        conversation1.subject = "1st conversation"
        conversationArray.append(conversation1)

        let conversation2 = Conversation()
        conversation2.subject = "2nd Conversation"
        conversationArray.append(conversation2)

        let conversation3 = Conversation()
        conversation3.subject = "3rd conversation"
        conversationArray.append(conversation3)

        tableView.estimatedRowHeight = tableView.rowHeight
        tableView.rowHeight = UITableViewAutomaticDimension

        self.showNavBar()
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    





extension HomeTabViewController: UITableViewDataSource, UITableViewDelegate, SwipeTableViewCellDelegate


    //MARK: - UITableViewDataSource Protocol Implementation
    /***************************************************************/


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

        return conversationArray.count
    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 


        guard let cell = tableView.dequeueReusableCell(withIdentifier: "homeTabCell", for: indexPath) as? ConversationCell
        else
            fatalError("The dequeued cell is not an instance of homeTabCell.")
        

        //To make the cell Swipeable via SwipeCellKit
        cell.delegate = self


        print("CELL_FOR_ROW_AT - indexPath.row = \(indexPath.row) | Conversation.subject = \(conversationArray[indexPath.row].subject)")

        //Initializing the cell
        cell.distanceLabel.text = conversationArray[indexPath.row].distance
        cell.locationLabel.text = conversationArray[indexPath.row].location
        cell.dateLabel.text = conversationArray[indexPath.row].date
        cell.subjectLabel.text = conversationArray[indexPath.row].subject
        cell.bodyLabel.text = conversationArray[indexPath.row].body
        cell.usernameLabel.text = conversationArray[indexPath.row].username
        cell.profileImageView.image = conversationArray[indexPath.row].profilePhoto

        return cell
    

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 


        guard let cell = tableView.dequeueReusableCell(withIdentifier: "homeTabCell", for: indexPath) as? ConversationCell
            else
                fatalError("The dequeued cell is not an instance of homeTabCell.")
        
         print("DID_SELECT_ROW_AT - Selected Row = \(indexPath.row) | cell.subjectLabel.text = \(cell.subjectLabel.text!)")
 

我已经尝试在自定义单元格中使用所有不同的标签,结果相同:它总是打印出 XIB 文件的相应默认文本值。

知道为什么(见鬼)会发生这种情况吗? :) 非常感谢!

【问题讨论】:

【参考方案1】:

看看你在didSelectRowAt做什么!

guard let cell = tableView.dequeueReusableCell(withIdentifier: "homeTabCell", for: indexPath) as? ConversationCell
    else
        fatalError("The dequeued cell is not an instance of homeTabCell.")

您正在使一个 单元出队!从dequeueReusableCell 返回的单元格始终与您在 XIB 文件中设计的单元格相同。

您应该在表格视图中获取与索引路径对应的单元格,而不是使新单元格出队:

let cell = tableView.cellForRow(at: indexPath)
// print cell contents...

或者只是访问你拥有的数组:

let conversation = conversationArray[indexPath.row]
// print conversation's properties...

【讨论】:

非常感谢,这解决了问题!就您而言,我的错误是认为 dequeueReusableCell() 在使 new 单元出列时返回参数行中的现有单元。【参考方案2】:

conversationArray 添加数据时,您只是插入修改后的subject。更新 all 其他属性以及 belo:-

let conversation1 = Conversation()
        conversation1.subject = "1st conversation"
conversation1.location = "India"
conversation1.distance= "456 Ft"
conversation1.date= "Yesterday, 11:15PM"
        conversationArray.append(conversation1)

您需要为所有对话对象分配属性值,即conversation2conversation3

【讨论】:

【参考方案3】:

问题不完全是问题,您不只是访问正确的内容,您应该做的是使用 tableview 函数 didSelect 提供的索引路径访问对话单元格。

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 


    guard let cell = tableView.dequeueReusableCell(withIdentifier: "homeTabCell", for: indexPath) as? ConversationCell
        else
            fatalError("The dequeued cell is not an instance of homeTabCell.")
    
     print("DID_SELECT_ROW_AT - Selected Row = \(indexPath.row) | cell.subjectLabel.text = \(conversationArray[indexPath.row].subject)")
 

【讨论】:

【参考方案4】:

这样做..

  let cell = tableView.cellForRow(at: indexPath)
  print(cell.label.text)

【讨论】:

谢谢,正如@Sweeper 所描述的那样,这就是问题所在。【参考方案5】:

您正在将值传递给唯一的主题,

    let conversation1 = Conversation()
    conversation1.subject = "1st conversation"
    conversationArray.append(conversation1)

所以主题随着更新的值而变化,其他的保持默认值

class Conversation 
var distance = "123 ft."
var location = "123 Market St"
var date = "Yesterday, 10:45AM"
var subject = "Default subject."
var body = "Default body"


   // var subject = "My Subject"
   // var body = "My Body"

var username = "worldsurfer"
var profilePhoto = UIImage(named: "profilePhoto")

尝试像这样给予,

    let conversation1 = Conversation()
    conversation1.subject = "1st conversation"
    conversation1.distance = "500 ft."
    conversation1.location = "2nd West Street"
    conversation1.date = "Yesterday, 4:00 PM"
    conversation1.body = "1st conversation body, just a Try"
    conversation1.username = "ben"
    conversationArray.append(conversation1)

    let conversation2 = Conversation()
    conversation2.subject = "2nd conversation"
    conversation2.distance = "160 ft"
    conversation2.location = "New Southern Street"
    conversation2.date = "Yesterday, 11:45 AM"
    conversation2.body = "2nd conversation body, just a Try"
    conversation2.username = "Abirami"
    conversationArray.append(conversation2)

谢谢..!

【讨论】:

以上是关于自定义 TableViewCell 中的标签始终返回其初始化值的主要内容,如果未能解决你的问题,请参考以下文章

标签显示超出我的自定义 TableViewCell 范围并通过 swift 设置自动布局

自定义 TableViewCell 中忽略自动布局

单击按钮时将默认 TableViewCell 更改为自定义子类

以编程方式将 UILabel 添加到自定义 tableViewCell

自定义 tableviewcell 动态高度未根据约束更新(以编程方式自动布局)

每个 tableViewCell 中的 Firebase 数据库观察者