从UIViewController向自定义UITableViewCell传递变量

3

以下是我如何在UIViewController中使用我的自定义单元格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类:(单元格GUI在Storyboard中创建)

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

使用结果如下:(SomeButton是在RunningTableViewCell内部的一个子视图)

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

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

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


1
有几种方法可以实现,比如将单元格的标签设置为识别该单元格是否为最后一个或第一个。 - Ilesh P
它返回“result: nil nil”,因为awakeFromNib在您设置cellForRowAtIndexPath中的值之前被调用。 - pbasdf
@Arefly 这取决于你想在哪里/何时/为什么获取这些值。你能详细解释一下你想做什么吗? - pbasdf
@pbasdf 我想知道当前单元格是否为第一个/最后一个单元格,并根据此对UI进行更改。我还想知道一些将在UI中的值。 (请参见更新的问题)谢谢 :) - He Yifei 何一非
@Arefly 我建议你尝试在 isTopisBottom 变量上使用自定义 setter,在这些值改变时立即更新 UI。 - pbasdf
显示剩余7条评论
4个回答

4

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

因此,RunningTableViewCell中的每个单元格的awakeFromNib代码在委托方法func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell之前调用。这就是为什么awakeFromNib中的isTopisBottom都是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,您的答案完美适用于我的情况 :) - JihadiOS

1
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)")
        }
    }

并且使用单例方法...

如果我想传递多个数据怎么办? :) - He Yifei 何一非
您正在使用“单例”方法。 - Ilesh P
您可以使用 singleton 方法,也可以使用单元格方法自定义方法来设置值,并从索引路径行表视图方法中调用。谢谢。 - Ilesh P
标签一直返回0 :( - He Yifei 何一非

1

您需要在单元格中覆盖 prepareForReuse 方法。并将其从 tableView:indexPath: 中移除。这样,当您滚动单元格时,它将被重用,但 isBottonisTop 变量将被重置。

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

RunningTableViewCell 中添加这些代码后,我找不到任何区别? - He Yifei 何一非
我猜你需要确定这个单元格是顶部单元格还是底部单元格。这将在委托方法中稍后分配,因此print("result: \(self.isTop) \(self.isBottom)")始终会显示false(当单元格被创建时)。 - TomCobo

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

在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)")
}

祝你好运!


仍然存在重复使用单元格的问题 :( - He Yifei 何一非
糟糕!……尝试在定义这些变量时设置初始值,就像这样: var isTop = false var isBottom = false - Basheer Alhader

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接