У динамических переключателей Tableview возникают проблемы, если я выбираю переключатель и включаю его немедленно, он не включается быстро - PullRequest
1 голос
/ 07 марта 2019

Я создал UITableView и динамически добавляю коммутатор в каждую ячейку, база является обязательной.если я выбираю выключатель и включаю его, сразу же выбираю следующий выключатель и включаю его, у него возникает проблема с изменением состояния переключателя, а ранее выбранный выключатель отключается, это происходит только в том случае, если я быстро выбрал все переключатели.

enter image description here

вот изображение в этом я добавляю все переключатели динамически в соответствии с данными, и если я на первом переключателе это данные будут загружатьсяих в другой таблице.но если я быстро выберу все переключатели и включу их, некоторые переключатели будут зависать только в выключенном состоянии.если я нажму на внешней стороне таблицы, она исчезнет, ​​и если снова загрузлю таблицу, в этот раз я смогу увидеть все выбранные и ранее включенные (вкл.), переключатель выключается (не все, кроме случайных, это происходит)

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    var cell = tableView.dequeueReusableCell(withIdentifier: "cell")

    if let _ = cell {} else {
        cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
    }
    if let d = self.data {
        cell?.textLabel?.text = d[indexPath.row]
        let switchView = UISwitch(frame: .zero)
        switchView.setOn(self.isFolderIsAdded(folderName: d[indexPath.row]), animated: true)
        switchView.tag = indexPath.row // for detect which row switch Changed
        switchView.addTarget(self, action: #selector(self.switchChanged(_:)), for: .valueChanged)
        cell?.accessoryView = switchView

    }
    return cell!
}

func isFolderIsAdded(folderName:String) -> Bool{
    for   val in listOfSelectedFolder{
        if(folderName == val ){
            return true
        }
    }
    return false;
}

@objc func switchChanged(_ sender : UISwitch!){
    if let d = self.data {
        if(sender.isOn){
            self.delegate?.selectedSubFolder(name: d[sender.tag])
           } else {
            self.delegate?.deleteFilesFromFolder(folderName: d[sender.tag])
        }
    }
}

Ответы [ 3 ]

2 голосов
/ 07 марта 2019

Это проблема повторного использования.когда вы прокручиваете tableView, ячейка затем используется повторно.переключатель на нем будет сброшен.

Вам необходимо следовать шаблонам MVC Design.Используйте модель, чтобы помочь вам.Как это

class CellModel {
  var name = ""
  var switchOn = false
}

var dataSource = [CellModel]()

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! CustomCell
    cell.model = dataSource[indexPath.row]
    return cell
}
class CustomCell: UITableViewCell {

  var model: CellModel? {
     didSet {
     switchView.isOn = model?.switchOn ?? false
    }
  }
  init(xxxx) {
     switchView.addTarget(self, action:#selector(self.switchChanged(_:)), for: .valueChanged)
  }


  @objc func switchChanged(_ sender : UISwitch!){
       model.switchOn = sender.isOn
   }
  }
0 голосов
/ 07 марта 2019

Я попробовал ваш код с некоторыми изменениями, он работает нормально.Это не проблема с tableView.dequeueReusableCell.Пожалуйста, попробуйте код ниже.

import UIKit

class FirstViewController: UIViewController,UITableViewDelegate, UITableViewDataSource{



@IBOutlet weak var tableView: UITableView!
var listOfSelectedFolder = ["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""]
var listOfSelectedFolder2 = ["sample text 0","sample text 1","sample text 2","sample text 4","sample text 5","sample text 6","sample text 7","sample text 8","sample text 9","sample text 10","sample text 11","sample text 12","sample text 13","sample text 14","sample text 15","sample text 16","sample text 17","sample text 18","sample text 19","sample text 20","sample text 21","sample text 22","sample text 23","sample text 24","sample text 25","sample text 26","sample text 27","sample text 28","sample text 29","sample text 30","sample text 31","sample text 32","sample text 33","sample text 34","sample text 35","sample text 36","sample text 37","sample text 38","sample text 39","sample text 40"]

override func viewDidLoad() {
    super.viewDidLoad()
    self.tableView.delegate = self
    self.tableView.dataSource = self
    // Do any additional setup after loading the view, typically from a nib.
}


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

/// tableview datasouce methodes

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return listOfSelectedFolder2.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 50
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    var cell = tableView.dequeueReusableCell(withIdentifier: "cell")

    if let _ = cell {} else {
        cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
    }
    let foldername = listOfSelectedFolder2[indexPath.row]
        cell?.textLabel?.text = foldername
        let switchView = UISwitch(frame: .zero)
        switchView.setOn(self.isFolderIsAdded(folderName: foldername), animated: true)
        switchView.tag = indexPath.row // for detect which row switch Changed
        switchView.addTarget(self, action: #selector(self.switchChanged(_:)), for: .valueChanged)
        cell?.accessoryView = switchView

    return cell!
}
func isFolderIsAdded(folderName:String) -> Bool{

    return listOfSelectedFolder.contains(folderName);
}

@objc func switchChanged(_ sender : UISwitch!){
        if(sender.isOn){

            self.listOfSelectedFolder.insert(self.listOfSelectedFolder2[sender.tag], at: sender.tag)
        } else {
            self.listOfSelectedFolder.remove(at: sender.tag)
            self.listOfSelectedFolder.insert("", at: sender.tag)
        }
}
}

В случае, если проблема все еще остается, возможно, обновления пользовательского интерфейса происходят в фоновом потоке.Поэтому убедитесь, что код обновления пользовательского интерфейса выполняется в главном потоке.

dispatch_async(dispatch_get_main_queue(), {code})

или

DispatchQueue.main.async {code}
0 голосов
/ 07 марта 2019

При повторном использовании tableViewCell Всегда не забывайте использовать.

1 - метод prepareForReuse в классе tableViewCell

2 - напишите else условия для всех if conditions, особенно если вы обновляете любой пользовательский интерфейс в if condition

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "cell")

if let _ = cell {} else {
    cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
}
if let d = self.data {
    cell?.textLabel?.text = d[indexPath.row]
    let switchView = UISwitch(frame: .zero)
    switchView.setOn(self.isFolderIsAdded(folderName: d[indexPath.row]), animated: true)
    switchView.tag = indexPath.row // for detect which row switch Changed
    switchView.addTarget(self, action: #selector(self.switchChanged(_:)), for: .valueChanged)
    cell?.accessoryView = switchView

}else{
// Update your UI if data not found like turn your switch off etc ... 
    }
    return cell!
}

3- Или Возможно, проблема с вашим симулятором после того, как обновление симулятора Xcode 9.0 теперь не так хорошо, как до Xcode 8.X

...