从 UIViewController 将变量传递给自定义 UITableViewCell

Posted

技术标签:

【中文标题】从 UIViewController 将变量传递给自定义 UITableViewCell【英文标题】:Pass variable to custom UITableViewCell from UIViewController 【发布时间】:2016-03-12 11:42:55 【问题描述】:

这是我在UIViewController 中使用自定义 UITableViewCell RunningTableViewCell 的方法:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as! RunningTableViewCell

    //.......

    cell.isTop = false
    if(indexPath.row == 0)
        cell.isTop = true
    

    cell.isBottom = false
    if(indexPath.row == myArray.count-1)
        cell.isBottom = true
    

    return cell

这是我的RunningTableViewCell 课程:(Cell 的 GUI 是在情节提要中制作的)

class RunningTableViewCell: UITableViewCell 

    //@IBOutlet ...
    @IBOutlet weak var myButton: SomeButton!

    var isTop: Bool?
    var isBottom: Bool?

    override func awakeFromNib() 
        super.awakeFromNib()

        print("result: \(self.isTop) \(self.isBottom)")

        myButton.isTop = self.isTop
        myButton.isBottom = self.isBottom
    

它返回result: nil nil

结果的用法是:(SomeButtonRunningTableViewCell里面的子视图)

class SomeButton: UIButton 
    var isTop = false
    var isBottom = false

    override func drawRect(rect: CGRect) 
        if(isTop)
            // DO SOMETHING...
        
        if(isBottom)
            // DO SOMETHING...
        
    

那么如何将数据传递给 RunningTableViewCell?

【问题讨论】:

有几种方法可以做,比如你设置单元格的标签来识别这个单元格是最后一个还是第一个。 @ilesh 如果我想传递超过 1 个数据怎么办? :) 它返回 "result: nil nil" 因为在您设置 cellForRowAtIndexPath 中的值之前调用了 awakeFromNib @pbasdf 那么我应该在哪里调用以获得cellForRowAtIndexPath中设置的值? @Arefly 这取决于您想要这些值的位置/时间/原因。你能解释更多你想做的事情吗? 【参考方案1】:

awakeFromNib 在视图及其子视图被分配和初始化后立即调用。

因此,在委托方法func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 之前调用每个单元格的RunningTableViewCellawakeFromNib 中的代码。这就是为什么isTopisBottomawakeFromNib 中是nil

您可以在RunningTableViewCell 中定义方法,该方法将使用此变量加载单元格。

func load(isTop: Bool, isBottom: Bool) 
    self.isTop = isTop
    self.isBottom = isBottom

    // Update cell UI as you wish

最后在你的视图控制器中重写委托方法func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as! RunningTableViewCell

    let isTop = indexPath.row == 0
    let isBottom = indexPath.row == myArray.count-1

    cell.load(isTop, isBottom: isBottom)

    return cell

【讨论】:

感谢@Misternewb,您的回答非常适合我的情况:)【参考方案2】:

您需要覆盖单元格中的prepareForReuse。并将其从tableView:indexPath: 中删除。因此,当您滚动时,单元格将被重用,但 isBottonisTop 变量将被重置。

override func prepareForReuse() 
    self.isBottom = false
    self.isTop = false

【讨论】:

将这些代码添加到RunningTableViewCell后找不到任何区别? 我想您需要确定单元格是顶部单元格还是底部单元格。这将在稍后由委托方法分配,因此print("result: \(self.isTop) \(self.isBottom)") 将始终显示为 false(在创建单元格时)。【参考方案3】:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as! RunningTableViewCell

    //.......

    cell.isTop = false
    if(indexPath.row == 0)
        cell.isTop = true
        cell.tag=100
    

    cell.isBottom = false
    if(indexPath.row == myArray.count-1)
        cell.isBottom = true
        cell.tag=200
    

    return cell

并且也得到这样的......

class RunningTableViewCell: UITableViewCell 

        //@IBOutlet ...

        var isTop: Bool?
        var isBottom: Bool?

        override func awakeFromNib() 
            super.awakeFromNib()
            if (self.tag==100)
            
                isTop=true
            
            else if (self.tag==200) 
                isBottom=true
            
            else
                isTop=false
                isBottom=false
            

            print("result: \(self.isTop) \(self.isBottom)")
        
    

还可以使用单例方法...

【讨论】:

如果我想传递超过 1 个数据怎么办? :) 你使用singleton方法 您可以使用singleton 方法,也可以使用单元格方法自定义方法来设置值及其从索引路径行表视图方法中的调用。谢谢 标签一直返回0 :(【参考方案4】:

您可以通过在单元格中调用自定义方法来解决此问题,例如,

在 UIViewController 内部:

//.......

cell.isTop = false
if(indexPath.row == 0)
    cell.isTop = true


cell.isBottom = false
if(indexPath.row == myArray.count-1)
    cell.isBottom = true


cell.UpdateViews()

return cell

TableViewCell 内部:

//@IBOutlet ...

var isTop: Bool?
var isBottom: Bool?

func updateViews() 
  print("result: \(self.isTop) \(self.isBottom)")

祝你好运!

【讨论】:

重复使用单元格仍然有同样的问题:( 糟糕! ...当你像这样定义这个有价值的东西时尝试设置初始值: var isTop = false var isBottom = false

以上是关于从 UIViewController 将变量传递给自定义 UITableViewCell的主要内容,如果未能解决你的问题,请参考以下文章

使用 UIViewController 中的表将变量传递给详细视图控制器(不是 UITableViewController !!)

将变量从 UIViewController 传递到 SK 场景

将变量从 customCell.xib 的按钮传递到另一个 UIViewController

变量未传递给 UIView

Objective C - 将一个值从 UIViewController 传递给 UIView - 我不断得到 null

将 NSArray 从 UIViewController 传递到子视图 [重复]