2016-03-08 31 views
2

當我選擇它時(並在再次選擇時刪除),我將圖像添加到表視圖行(實際上,我似乎將它添加到行的單元格中)。表視圖由原型單元組成。添加到UITableViewCell的圖像在滾動時出現在錯誤的行中

這可行,但是當我滾動並回到之前選擇的行時,圖像將位於另一行。此外,圖像也出現在其他行中。

我的猜測是這樣的,因爲這些單元格在滾動時被重新使用。 這裏有一個小樣本項目的代碼:回來這個觀點控制器還當

import UIKit 

class MyTableViewController: UITableViewController { 

    // Using integers for simplicity, should work with strings, too. 
    var numbers = [Int]() 

    override func viewDidLoad() { 
    super.viewDidLoad() 

    for i in 0..<50 { 
     numbers.append(i) 
    } 
    } 

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCellWithIdentifier("TestCell", forIndexPath: indexPath) 
    cell.textLabel?.text = "\(numbers[indexPath.row] + 1)" 

    return cell 
    } 

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return numbers.count 
    } 

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    let cell = tableView.cellForRowAtIndexPath(indexPath)! 

    if let myImage = curCell.viewWithTag(10) as? MyImage { 
     myImage.removeFromSuperview() 
    } else { 
     let myImage = myImage() 
     myImage.tag = 10 
     cell.addSubview(myImage) 
    } 

    } 

我需要有圖像的住宿正確的行中。解決這個問題的正確方法是什麼? 任何建議非常感謝!

編輯:我試圖實現馬特的答案,但我似乎失去了一些東西,因爲問題仍然是一樣的。

編輯2:更新,按預期工作。

import UIKit 

class ListItem { 

    var name: String! 
    var showsImage = false 

    init(name: String) { 
    self.name = name 
    } 

} 


class MyTableViewController: UITableViewController { 

    var listItems = [ListItem]() 

    override func viewDidLoad() { 
    super.viewDidLoad() 

    for i in 0..<50 { 
     let listItem = ListItem(name: "row \(i)") 
     listItems.append(listItem) 
    } 
    } 


    // MARK: - Table view data source 

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCellWithIdentifier("TestCell", forIndexPath: indexPath) 

    cell.textLabel?.text = "\(listItems[indexPath.row].name)" 

    if listItems[indexPath.row].showsImage { 
     let myImage = myImage 
     myImage.tag = 10 
     cell.addSubview(myImage) 
    } else { 
     if let myImage = cell.viewWithTag(10) as? myImage { 
     myImage.removeFromSuperview() 
     listItems[indexPath.row].showsImage = false 
    } 

    return cell 
    } 

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return listItems.count 
    } 

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    let cell = tableView.cellForRowAtIndexPath(indexPath)! 

    if let myImage = cell.viewWithTag(10) as? myImage { 
     myImage.removeFromSuperview() 
     listItems[indexPath.row].showsImage = false 
    } else { 
     listItems[indexPath.row].showsImage = true 
     tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None) 
    } 
    } 

} 

EDIT 3:作爲無光澤建議的,這裏的一個替代解決方案,以高於該子類的UITableViewCell代替使用標籤的圖像的代碼。

import UIKit 

class MyTableViewCell: UITableViewCell { 

    var myImage = MyImage() 

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) { 
    super.init(style: style, reuseIdentifier: reuseIdentifier) 

    myImage.hidden = true 
    addSubview(myImage) 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

} 


class ListItem { 

    var name: String! 
    var showsImage = false 

    init(name: String) { 
    self.name = name 
    } 

} 

class MyTableViewController: UITableViewController { 

    var listItems = [ListItem]() 

    override func viewDidLoad() { 
    super.viewDidLoad() 

    for i in 0..<50 { 
     let listItem = ListItem(name: "row \(i)") 
     listItems.append(listItem) 
    } 
    } 


    // MARK: - Table view data source 

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return listItems.count 
    } 

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = MyTableViewCell(style: .Default, reuseIdentifier: "TestCell") 

    cell.textLabel?.text = "\(listItems[indexPath.row].name)" 
    cell.myImage.hidden = !(listItems[indexPath.row].showsImage) 

    return cell 
    } 

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    let cell = tableView.cellForRowAtIndexPath(indexPath) as! MyTableViewCell 

    listItems[indexPath.row].showsImage = cell.myImage.hidden 
    cell.myImage.hidden = !cell.myImage.hidden 
    } 

} 

回答

5

問題是單元格在其他行中重複使用。當它們再次被調用時,cellForRowAtIndexPath。但是,當它是,你沒有提供有關該行圖像的信息。

解決方案:修復您的模型(即您在cellForRowAtIndexPath中諮詢的信息),以便了解圖像。在didSelect中,請勿直接修改單元格。相反,請修改型號並重新加載該單元。

+0

您好馬特,非常感謝您的幫助。我試着實現你的答案,並將代碼示例添加到我的帖子中。我仍然在做一些錯誤的事,如果你能夠快速瀏覽它,那將是一件好事。謝謝! – nontomatic

+0

非常好!你快到了。你只是犯了一個小小的邏輯錯誤。你的'cellForRow'有這樣的條件:'如果listItems [indexPath.row] .showsImage',但是你忘記了應該發生什麼_otherwise_。您需要添加一個'else'子句來刪除圖像。那時候,我認爲一切都會開始落實。換句話說,請記住'cellForRow'必須_completely_配置每個單元,因爲你永遠不知道單元是否被重用。 - 另外,請注意,您現在可能會多次將多個圖像視圖添加到同一個單元格。想想...! – matt

+0

再次感謝!我更新了代碼。事實上,它現在似乎工作!編輯:我剛剛讀過你的文章,我需要繼承UITableViewCell(我想避免,如果可能的話),並添加圖像作爲我隱藏和顯示的屬性,而不是每次都添加它? – nontomatic

相關問題