tableView.dequeueReusableCellWithIdentifier VS tableView.cellForRowAtIndexPath

时间:2015-11-06 05:12:34

标签: ios swift uitableview

我的Xcode是7.1。仿真器是iPhone6 通常我使用dequeueResuableCellWithIdentifier,但这次我遇到了问题。

我的问题是:
选择新行后,它不会清除我的orangeColor()。但取消选择indexPath的打印行是正确的。

我的解决方案是:
我从let cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath) as! MyCell;更改了 到
let cell = tableView.cellForRowAtIndexPath(indexPath) as! MyCell;
然后它解决了我的问题。背景颜色为clearColor()

以下是我的文件:
MyCell.swift:

import UIKit

class MyCell: UITableViewCell {
    @IBOutlet weak var myLabel : UILabel!
    @IBOutlet weak var myWebView : UIWebView!;
    //@IBOutlet weak var myView : UIView!;
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code.
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

ViewController.swift:

import UIKit

class ViewController: UIViewController,UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableViewObject: UITableView!

    var fruits = ["Apple", "Banana","Cherry", "Durian", "ElderBerry"];
    var selectedIndexPath : NSIndexPath?;
    override func viewDidLoad() {
        super.viewDidLoad()
        self.tableViewObject.delegate = self;
        self.tableViewObject.dataSource = self;
        // Do any additional setup after loading the view, typically from a nib.
    }
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
        return fruits.count;
    }
    func loadCellContent(acell : UITableViewCell, indexPath : NSIndexPath, color: UIColor){
        let cell = acell as! MyCell;
        cell.myLabel.text = String(UnicodeScalar(65 + indexPath.row));
        cell.myWebView.loadHTMLString(fruits[indexPath.row], baseURL: nil);
        cell.myWebView.scrollView.bounces = false;
        cell.myWebView.scrollView.scrollEnabled = false;
        cell.myWebView.userInteractionEnabled = false;
        cell.backgroundColor = color;
        cell.myLabel.backgroundColor = color;
        cell.myWebView.backgroundColor = color;
    }
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
        let cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath) as! MyCell;
        self.loadCellContent(cell, indexPath: indexPath, color: UIColor.clearColor());
        return cell;
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int{
        return 1;
    }
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        //let cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath) as! MyCell;
        let cell = tableView.cellForRowAtIndexPath(indexPath) as! MyCell;
        self.loadCellContent(cell, indexPath: indexPath, color : UIColor.orangeColor());
    }
    func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
        //let cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath) as! MyCell;
        let cell = tableView.cellForRowAtIndexPath(indexPath) as! MyCell;
        self.loadCellContent(cell, indexPath: indexPath,color: UIColor.clearColor());
        print("Hellos", indexPath.row);

    }
}

我的问题是:
1.方法dequeueReusableCellWithIdentifercellForRowAtIndexPath之间的主要区别是什么? 2.何时使用第一个或第二个,我怎么知道? 这次我使用一个教程中的试验/错误。

更新:
我的背景是物理学和一点点计算机科学。请不要对我的天真问题等生气。

2 个答案:

答案 0 :(得分:1)

tableview尝试在内存中始终没有所有索引路径的单元格对象实例:

  • ' dequeueReusableCellWithIdentifer'回收一个单元格或创建它,应该在' cellForRow ...'中调用。此始终返回一个单元格实例,可以是新单元格实例,也可以是之前不再可见的单元格实例。在此之后准备要显示的单元格。

  • ' cellForRowAtIndexPath(indexPath:NSIndexPath) - > UITableViewCell的? // 如果单元格不可见或索引路径超出范围则返回nil'这不会创建单元格,只允许您访问它们。我认为应该尽可能避免意外泄漏和其他对tableView的干扰。

关于您的' setSelected'问题:

  • 在单元类中实现重用准备(将所有值设置为默认值)是一个很好的想法。
  • 你不应该再次在'didSelectRow'中加载单元格内容。 (用户刚刚点击它,所以它已加载)
  • 您可能需要更改单元格中的橙色/清晰颜色' setSelected'

答案 1 :(得分:1)

这两种方法有不同的用途。

  • 如果需要,dequeueReusableCellWithIdentifier:indexPath:会实例化一个新单元格,但会重复使用之前已滚动屏幕的单元格(如果有的话)。

    您只能从tableView:cellForRowAtIndexPath:

  • 调用此方法
  • cellForRowAtIndexPath:方法(不要与类似命名的tableView:cellForRowAtIndexPath:方法混淆)不会实例化新单元格,而只是用于获取对先前实例化单元格的引用目前可见。如果单元格不可见(例如,已在屏幕上滚动),则返回nil

    您在tableView:didSelectRowAtIndexPath:tableView:didDeselectRowAtIndexPath:等方法中使用此方法,因为您只是尝试获取对现有单元格的引用,而不是实例化新单元格。

-

请注意,在您的代码示例中,您不仅会loadCellContent,还会tableView:cellForRowAtIndexPath:tableView:didSelectRowAtIndexPath:致电tableView:didDeselectRowAtIndexPath:。我建议将单元格的初始配置(例如,loadCellContent,你只能从tableView:cellForRowAtIndexPath:调用)与调整背景颜色(你将在{{1中)进行分离。 }和didSelect...)。后两种方法通常不会再次重新配置整个单元格,而只是更新背景颜色(或执行适合显示选择的任何装饰)。

此外,您还需要确保didDeselect...检查配置背景颜色时是否选中了单元格。用户可能选择一个单元格,将其滚出屏幕,然后在屏幕上向后滚动,在这种情况下tableView:cellForRowAtIndexPath:必须检查单元格是否被选中以便设置背景颜色。

例如:

tableView:cellForRowAtIndexPath: