簡體   English   中英

自定義UITableViewCell內部的UIButton導致在多個單元格中選擇按鈕

[英]UIButton inside custom UITableViewCell causes button to be selected in multiple cells

UITableView的目標是在名稱旁邊顯示一個自定義樣式的復選框。 但是以某種方式,當我點擊復選框時,UITableView中的多個復選框被選中。

我已經用Google搜索並實施了來自不同問題的多種解決方案,但似乎沒有一個可行。

自定義UITableViewCell

import UIKit

class NameTableViewCell: UITableViewCell {

    var name = UILabel()

    let checkboxImage_unchecked = UIImage(named: "cellViewCheckbox_unchecked")
    let checkboxImage_checked = UIImage(named: "cellViewCheckbox_checked")

    let checkbox:UIButton

    weak var delegate:HandleCellInteractionDelegate?

    override init(style: UITableViewCellStyle, reuseIdentifier: String!) {
        self.checkbox = UIButton(frame: CGRectMake(35, 16, self.checkboxImage_unchecked!.size.width/2, self.checkboxImage_unchecked!.size.height/2))
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        self.backgroundColor = UIColor.transparant()

        self.checkbox.setBackgroundImage(self.checkboxImage_unchecked, forState: .Normal)
        self.checkbox.setBackgroundImage(self.checkboxImage_checked, forState: .Selected)

        self.name = UILabel(frame: CGRectMake(97,18,200, 30))

        self.addSubview(self.name)
        self.addSubview(self.checkbox)
    }

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

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

    func checkboxPushed(sender:AnyObject){
        self.checkbox.selected = !self.checkbox.selected
        self.delegate?.didPressButton(self)            
    }

在該協議中,我聲明了didPressButton方法作為按下按鈕時的回調(委托需要實現它)

協議

import UIKit

protocol HandleCellInteractionDelegate:class {
    func didPressButton(cell:NameTableViewCell)
}

ViewController

import UIKit

class NameViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, HandleCellInteractionDelegate{

    var nameView:NameView {
        get {
            return self.view as! NameView
        }
    }

    var names:[Name]?
    var firstLetters:[String]?

    let cellIdentifier = "nameCell"

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        //self.view.backgroundColor = UIColor.darkSalmon()
    }

    override func loadView() {
        let bounds = UIScreen.mainScreen().bounds
        self.view = NameView(frame: bounds)
        if(NSUserDefaults.standardUserDefaults().objectForKey("gender") !== nil){
            self.loadJSON()
            self.getFirstLetters();
            self.nameView.tableView.delegate = self;
            self.nameView.tableView.dataSource = self;
            self.nameView.tableView.registerClass(NameTableViewCell.classForCoder(), forCellReuseIdentifier: "nameCell")
            self.nameView.tableView.separatorStyle = .None
            self.nameView.tableView.rowHeight = 66.5            }
    }

    func loadJSON(){
        let path = NSBundle.mainBundle().URLForResource("names", withExtension: "json")

        let jsonData = NSData(contentsOfURL: path!)


        self.names = NamesFactory.createFromJSONData(jsonData!, gender: NSUserDefaults.standardUserDefaults().integerForKey("gender"))
    }

    func getFirstLetters(){
        var previous:String = ""

        for name in self.names! {
            let firstLetter = String(name.name.characters.prefix(1))
            if firstLetter != previous {
                previous = firstLetter
                self.firstLetters?.append(firstLetter)
                print(firstLetter)
            }

        }
    }

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

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return (self.names!.count)
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        return nameCellAtIndexPath(indexPath)
    }

    func nameCellAtIndexPath(indexPath:NSIndexPath) -> NameTableViewCell {
        let cell = self.nameView.tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as! NameTableViewCell
        self.setNameForCell(cell, indexPath: indexPath)
        cell.delegate = self;
        cell.checkbox.addTarget(cell, action: "checkboxPushed:", forControlEvents: .TouchUpInside)
        return cell
    }

    func setNameForCell(cell:NameTableViewCell, indexPath:NSIndexPath) {
        let item = self.names![indexPath.row] as Name
        cell.name.text = item.name
    }

    func didPressButton(cell: NameTableViewCell) {
        print(cell)
    }

}

我在做什么錯,我該如何解決?

您必須保存復選框狀態。 在您的模型(名稱)中再添加一個屬性checkboxStatus,希望您擁有indexpath.row。 在nameCellAtIndexPath中的此行之后

cell.delegate = self;

像這樣設置標簽

cell.tag = indexPath.row;

在委托方法中,

func didPressButton(cell: NameTableViewCell) {
    print(cell)
    let item = self.names![cell.tag] as Name
    item.checkboxstatus = cell.checkbox.selected
}

只是一項重要的改變,

func nameCellAtIndexPath(indexPath:NSIndexPath) -> NameTableViewCell {
    let cell = self.tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as! NameTableViewCell
    self.setNameForCell(cell, indexPath: indexPath)
    cell.delegate = self;
    cell.tag = indexPath.row;
    cell.checkbox.addTarget(cell, action: "checkboxPushed:", forControlEvents: .TouchUpInside)
    let item = self.names![cell.tag] as Name
    cell.checkbox.selected = item.checkboxstatus
    return cell
}

干杯!

發生這種情況是因為UITableViewCell被重用了。

當您按下復選框時,您更改了單元格,因此需要在數據源模型中對其進行跟蹤。

cellForRowAtIndexPath您必須添加條件以檢查該復選框是否已選中。 然后,您將顯示相應的視圖。

編輯:在您的示例中,您需要檢入nameCellAtIndexPath是否選中了該復選框,然后正確顯示它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM