如何避免tableview单元的可重用性?

时间:2017-07-04 17:24:08

标签: ios swift uitableview

当我点击indexpath.row == 0处的选择按钮或任何其他时,仅使用相应的"会话标签值"会改变,但在这里不会发生。它会改变下面的单元格值,即indexpath == 7或8,我认为这里是单元格的重用,所以我怎么能避免它。

我的代码如下所示。

1.UITableViewCell类:

import UIKit

class DemoTableViewCell: UITableViewCell {


    @IBOutlet weak var mSelectButton: UIButton!
    @IBOutlet weak var mDateLabel: UILabel!
    @IBOutlet weak var mSessionLabel: UILabel!    

    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
    }
}
  1. ViewController类: -

    导入UIKit

        class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
            var month_year = ""
            var fromYear = ""
            var toYear = ""
            var monthYearList = ""
            var monthYearListArray = [String]()
            let picker : UIDatePicker = UIDatePicker()
    
            var from_date = ""
            var to_date = ""
    
            //
            var selectedTagValue = Int()
            var aSheetValue = ""
            var isFromActionSheet = Bool()
            var isFromFinalClick = Bool()
            var intArray = [Int]()
    
            @IBOutlet weak var mTableView: UITableView!
    
            // MARK:- ViewController Life Cycle Methods
    
            override func viewDidLoad() {
                super.viewDidLoad()
            }
    
            override func viewWillAppear(_ animated: Bool) {
                self.printDatesBetweenInterval(self.dateFromString("2017-07-01"), self.dateFromString("2017-07-12"))
            }
    
            //MARK:- UITableViewDataSource and Delegate Methods
    
            func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    
                return monthYearListArray.count
            }
    
            func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
                let cell = tableView.dequeueReusableCell(withIdentifier: "DemoTableViewCell")! as! DemoTableViewCell
    
                cell.mDateLabel.text = monthYearListArray[indexPath.row]
    
                if isFromActionSheet{
    
                    if indexPath.row == selectedTagValue{
                        cell.mSessionLabel.text = aSheetValue
                        isFromActionSheet = false
                    }
                }
    
                cell.mSelectButton.tag = indexPath.row
                print("cell.mButtonOutlet.tag: \(cell.mSelectButton.tag)")
    
                cell.mSelectButton.addTarget(self, action: #selector(ViewController.actionOnSelectButtonClick(_:)), for: .touchUpInside)
    
                if isFromFinalClick{
                    if cell.mSessionLabel.text == "Full Day"{
                        self.intArray.append(1)
    
                    }else if cell.mSessionLabel.text == "First Half"{
                        self.intArray.append(2)
                    }else{
                        self.intArray.append(3)
                    }
                }
    
                return cell
            }
    
    
            // MARK:- IBAction Methods
    
            func actionOnSelectButtonClick(_ sender: UIButton)  {
                let mButton : UIButton = sender
                selectedTagValue = mButton.tag
                print("selectedTagValue: \(selectedTagValue)")
                isFromActionSheet = true
                openActionSheet()
            }
    
            // Submit Button
    
            @IBAction func actionOnSubmitButton(_ sender: Any) {
                isFromFinalClick = true
                mTableView.reloadData()
                print("intArray list: \(intArray)")
    
            }
    
            // MARK:- Instance Methods
    
            func openActionSheet()  {
    
                // 1
                let optionMenu = UIAlertController(title: nil, message: "Select Session", preferredStyle: .actionSheet)
    
                // 2
                let fullDayAction = UIAlertAction(title: "Full Day", style: .default, handler: {
                    (alert: UIAlertAction!) -> Void in
                    print("Full Day")
                    self.aSheetValue = "Full Day"
                    self.mTableView.reloadData()
                })
    
                let firstHalfAction = UIAlertAction(title: "First Half", style: .default, handler: {
                    (alert: UIAlertAction!) -> Void in
                    print("First Half")
                    self.aSheetValue = "First Half"
                    self.mTableView.reloadData()
    
                })
                let secondHalfAction = UIAlertAction(title: "Second Half", style: .default, handler: {
                    (alert: UIAlertAction!) -> Void in
                    print("Second Half")
                    self.aSheetValue = "Second Half"
                    self.mTableView.reloadData()
    
                })
    
                //
                let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: {
                    (alert: UIAlertAction!) -> Void in
                    print("Cancelled")
                })
    
                // 4
                optionMenu.addAction(fullDayAction)
                optionMenu.addAction(firstHalfAction)
                optionMenu.addAction(secondHalfAction)
                optionMenu.addAction(cancelAction)
    
    
                // 5
                self.present(optionMenu, animated: true, completion: nil)
            }
    
    
            // MARK:- Date_List Method
    
            func printDatesBetweenInterval(_ startDate: Date, _ endDate: Date) {
                var startDate = startDate
                let calendar = Calendar.current
    
                let fmt = DateFormatter()
                fmt.dateFormat = "yyyy-MM-dd"
    
                while startDate <= endDate {
                    print(fmt.string(from: startDate))
                    self.monthYearList = fmt.string(from: startDate)
                    print("self.monthYearList: \(self.monthYearList)")
                    fmt.dateFormat = "yyyy-MM-dd"
                    monthYearListArray.append(fmt.string(from: startDate))
                    startDate = calendar.date(byAdding: .day, value: 1, to: startDate)!
                }
    
                print("monthYearListArray: \(monthYearListArray)")
                mTableView.reloadData()
            }
    
            func dateFromString(_ dateString: String) -> Date {
                let dateFormatter = DateFormatter()
                dateFormatter.dateFormat = "yyyy-MM-dd"
    
                return dateFormatter.date(from: dateString)!
            }
    
        }
    

2 个答案:

答案 0 :(得分:6)

不要避免重复使用单元格,而是确保所有UI元素始终处于已定义的状态

 if isFromActionSheet && indexPath.row == selectedTagValue{
     cell.mSessionLabel.text = aSheetValue
     isFromActionSheet = false
 } else {
     cell.mSessionLabel.text = [default value]
     isFromActionSheet = [default value]
 }

答案 1 :(得分:0)

正确的做法是,您需要始终在cellForRow中设置这些UI元素。

原因是UITableView没有准备用于显示的表视图单元格,直到用户尝试滚动到该位置(即用户试图查看该单元格时)。因此,重用单元格的想法是将一些单元格模板保留在重用位置,以便下次您的手机不需要再次从头创建所有内容。唯一需要做的就是再次将单元格设置为正确状态。这也将使滚动更加流畅。

通过设置UI元素,我的意思是每次调用cellForRow方法时都必须为单元格上的UI元素设置值。看看这段代码

if isFromActionSheet{//What if this if is not called? Your cell.mSessionLabel will not get set
    if indexPath.row == selectedTagValue{//What if this if is not called? Your cell.mSessionLabel will not get set
        cell.mSessionLabel.text = aSheetValue
        isFromActionSheet = false
    }
}

如果两个if语句中的任何一个不为真,那么单元格上的mSessionLabel将不会获得新值,并且可能会显示来自模板单元格的其他值。所以你必须在两个else语句中创建两个else语句add set mSessionLabel。