带有部分的表视图在数据更改时消失

问题描述

我在iOS中的表格视图有问题。

当我用不同的数据更新表时,该表消失了,再也不会返回。 例如,如果我仅更新“ sMetriCubi”变量,则下次完全消失该行。 如果我将我的应用程序放在后台,然后回到前台,则表修复本身。与我注销和登录相同。

视频:https://streamable.com/5cr03e

Storyboard

DashboardController.swift

import UIKit
import NVActivityIndicatorView

struct Lotto {
    var nome: String
    var settori: [Settore]
}

struct Settore {
    var nome: String
    var data: String
    var metriCubi: String
    var consiglioIrriguo: String
    var aperto: String?
    var salta: String?
    var incrementa: Int?
    var stato: String
    var comandoInCorso: String?
}

extension UIView {
    func clearConstraints() {
        for subview in self.subviews {
            subview.clearConstraints()
        }
        self.removeConstraints(self.constraints)
    }
}

extension UIApplication {
    class func topViewController(controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
        if let tabController = controller as? UITabBarController {
            return topViewController(controller: tabController.selectedViewController)
        }
        if let navController = controller as? UINavigationController {
            return topViewController(controller: navController.visibleViewController)
        }
        if let presented = controller?.presentedViewController {
            return topViewController(controller: presented)
        }
        return controller
    }
}

class DashboardController: UITableViewController,NVActivityIndicatorViewable,UITabBarControllerDelegate {
    
    @IBOutlet var lottoTableView: UITableView!
    @IBOutlet weak var allarmeLabel: UILabel!
    @IBOutlet weak var alarmImage: UIImageView!
    
    var avoidFirstReload: Int = 0
    var lotti = [Lotto]()
    var autoUpdate: Timer = Timer.init()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.tabBarController?.delegate = self
        
        lottoTableView.delegate = self
        lottoTableView.dataSource = self
        
        // self.view.viewWithTag(100)!.frame.size.height = 0    // Genera un errore di costraint
        
        if (avoidFirstReload == 0) {
            refreshList(self)
        }
    }
    
    func tabBarController(_ tabBarController: UITabBarController,didSelect viewController: UIViewController) {
         let tabBarIndex = tabBarController.selectedindex
         if tabBarIndex == 0 {
             refreshList(self)
         }
    }
    
    override func viewDidAppear(_ animated: Bool) {
        autoUpdate = Timer.scheduledTimer(timeInterval: 60.0,target: self,selector: #selector(autoUpdateFunc),userInfo: nil,repeats: true)
    }
    
    override func viewDiddisappear(_ animated: Bool) {
        autoUpdate.invalidate()
        UIApplication.shared.applicationIconBadgeNumber = 0
    }
    
    @objc func autoUpdateFunc() {
        refreshList(self)
    }
    
    @IBAction func refreshList(_ sender: Any) {
        startAnimating(CGSize(width: 30,height: 30),type: NVActivityIndicatorType.ballpulse,color: UIColor(red: 0/255,green: 133/255,blue: 119/255,alpha: 1),backgroundColor: UIColor.white)
        
        let defaults = UserDefaults.standard
        let token = defaults.string(forKey: "token")
        let username = defaults.string(forKey: "username")
        
        let param: [String: Any] = [
            "Funzione": "ListaLotti","Versione": App.Constants.interfaceVer,"Lingua": Locale.current.languageCode!,"Utente": username!,"Token_Accesso": token!,"Id_dispositivo": UIDevice.current.identifierForvendor!.uuidString,]
        
        App.MakeRequest(json: param) {
            resp in
            dispatchQueue.main.async {
                self.stopAnimating()
                if (resp["Errore"] == nil){
                    let reqStatus = resp["Stato"] as! String
                    if (reqStatus == "OK"){
                        var allarmiStr: String = ""
                        if (resp["Allarmi"] != nil) {
                            for allarme in resp["Allarmi"] as! [AnyObject] {
                                allarmiStr += (allarme["Allarme"] as! String) + "\n\n"
                            }
                        }
                        if (allarmiStr != "") {
                            allarmiStr.removeLast(2)
                            self.allarmeLabel.text = allarmiStr.replacingOccurrences(of: "\n\n",with: " ")
                            
                            let openTap = TapGesture(target: self,action: #selector(self.alertTap(sender:)))
                            openTap.numberOfTapsrequired = 1
                            self.allarmeLabel.isUserInteractionEnabled = true
                            self.allarmeLabel.addGestureRecognizer(openTap)
                            openTap.title = "alerts".localized()
                            openTap.text = allarmiStr
                            
                            let origImage = UIImage(named: "notification")
                            let tintedImage = origImage?.withRenderingMode(.alwaystemplate)
                            self.alarmImage.image = tintedImage
                            self.alarmImage.tintColor = .orange
                            
                            self.view.viewWithTag(100)!.frame.size.height = 44
                        } else {
                            self.view.clearConstraints()
                            self.view.viewWithTag(100)!.frame.size.height = 0
                        }
                        
                        self.lotti.removeAll()
                        let lottiArray = resp["Lotti"] as! [AnyObject]
                        if (lottiArray.count > 0) {
                            var settori = [Settore]()
                            var sNome: String
                            var sData: String
                            var sMetriCubi: String
                            var sCIVolume: String
                            var sAperto: String?
                            var sSalta: String?
                            var sMaggPerc: Int?
                            var sstato: String
                            var sComandoInCorso: String?
                            
                            for lotto in lottiArray {
                                settori.removeAll()
                                sNome = ""
                                sData = ""
                                sMetriCubi = ""
                                sCIVolume = ""
                                sAperto = nil
                                sSalta = nil
                                sMaggPerc = nil
                                sstato = ""
                                sComandoInCorso = nil
                                
                                for settore in lotto["Settori"] as! [AnyObject] {
                                    sNome = settore["Settore"] as! String
                                    sData = settore["Data"] as! String
                                    sMetriCubi = settore["Volume_Erogato"] as! String
                                    sCIVolume = settore["Consiglio_Irriguo_Volume"] as! String
                                    sAperto = settore["Aperta"] as? String
                                    sSalta = settore["Salta"] as? String
                                    sMaggPerc = settore["Maggiorazione_Consiglio_Irriguo_Percentuale"] as? Int
                                    sstato = settore["Stato_Settore"] as! String
                                    sComandoInCorso = settore["Comando_Settore_In_Corso"] as? String
                                    
                                    settori.append(Settore(nome: sNome,data: sData,metriCubi: sMetriCubi,consiglioIrriguo: sCIVolume,aperto: sAperto,salta: sSalta,incrementa: sMaggPerc,stato: sstato,comandoInCorso: sComandoInCorso))
                                }
                                self.lotti.append(Lotto(nome: lotto["Codice_Lotto"] as! String,settori: settori))
                            }
                        }
                        
                        self.lottoTableView.reloadData()
                    } else if (reqStatus == "KX") {
                        // Pulizia impostazioni
                        defaults.removeObject(forKey: "token")
                        
                        let storyBoard: UIStoryboard = UIStoryboard(name: "Main",bundle: nil)  // nome della storyboard
                        let newViewController = storyBoard.instantiateViewController(withIdentifier: "LoginView")    // nome della view
                        self.present(newViewController,animated: true,completion: nil)
                    } else {
                        let alert = UIAlertController(title: "error".localized(),message: resp["Messaggio"] as? String,preferredStyle: .alert)
                        alert.addAction(UIAlertAction(title: "close".localized(),style: .default,handler: nil))
                        self.present(alert,animated: true)
                    }
                } else {
                    var strError = resp["Errore"]
                    if (resp["Errore"] == nil) {
                        strError = "technicalError".localized()
                    }
                    let alert = UIAlertController(title: "error".localized(),message: strError as? String,preferredStyle: .alert)
                    alert.addAction(UIAlertAction(title: "close".localized(),handler: nil))
                    self.present(alert,animated: true)
                }
            }
        }
    }
    
    @objc func lottodisplayActionSheet(sender: ShowActions) {
        // ...
    }
    
    @objc func settoredisplayActionSheet(sender: ShowActions) {
        // ...
    }
    
    override func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = lottoTableView.dequeueReusableCell(withIdentifier: "customSettoreCell",for: indexPath) as! SettoreCell
        
        let settore = lotti[indexPath.section].settori[indexPath.row]
        cell.settoreNameLabel?.text = settore.nome
        
        // Stato settore
        
        if ((settore.stato == "SP") && ((settore.metriCubi as Nsstring).floatValue < (settore.consiglioIrriguo as Nsstring).floatValue)) {
            cell.settoreNameLabel.textColor = UIColor(red: 231/255,green: 76/255,blue: 60/255,alpha: 1)
        } else if (settore.stato == "SP") {
            cell.settoreNameLabel.textColor = UIColor(red: 23/255,green: 27/255,blue: 28/255,alpha: 1)
        } else if (settore.stato == "II") {
            cell.settoreNameLabel.textColor = UIColor(red: 46/255,green: 204/255,blue: 113/255,alpha: 1)
        } else if (settore.stato == "MA") {
            cell.settoreNameLabel.textColor = UIColor(red: 149/255,green: 165/255,blue: 166/255,alpha: 1)
        }
        
        let openTap = ShowActions(target: self,action: #selector(settoredisplayActionSheet(sender:)))
        openTap.numberOfTapsrequired = 1
        cell.settoreCommandImage.isUserInteractionEnabled = true
        cell.settoreCommandImage.addGestureRecognizer(openTap)
        openTap.buttons = []
        /*
        Tutti i comandi
        openTap.buttons = ["MA","AU","SA","AS","MG","AM","AP","CH","AC"]
        openTap.buttons_name = ["Manuale","Automatico","Salta","Annulla Salta","Maggiora","Annulla Maggiora","Apri","Chiudi","Annulla Comando"]
        */
        
        if ((settore.stato == "II") || (settore.stato == "SP")) {
            openTap.buttons.append("MA")
            openTap.buttons_name.append("commandManual".localized())
            if (settore.salta == "0") {
                openTap.buttons.append("SA")
                openTap.buttons_name.append("commandSkip".localized())
            } else {
                openTap.buttons.append("AS")
                openTap.buttons_name.append("commandDenySkip".localized())
            }
            if ((settore.incrementa != nil) && (settore.incrementa! > 0)) {
                openTap.buttons.append("MG")
                openTap.buttons_name.append("commandIncrease".localized())
            } else {
                openTap.buttons.append("AM")
                openTap.buttons_name.append("commandDenyIncrease".localized())
            }
        } else if ((settore.stato == "MA") && (settore.aperto == "1")) {
            openTap.buttons.append("AU")
            openTap.buttons.append("CH")
            openTap.buttons_name.append("commandAuto".localized())
            openTap.buttons_name.append("commandClose".localized())
        } else if ((settore.stato == "MA") && (settore.aperto == "0")) {
            openTap.buttons.append("AU")
            openTap.buttons.append("AP")
            openTap.buttons_name.append("commandAuto".localized())
            openTap.buttons_name.append("commandOpen".localized())
        }
        
        if (settore.comandoInCorso != nil) {
            openTap.buttons = []
            openTap.buttons.append("AC")
            openTap.buttons_name.append("commandCancel".localized())
        }
        openTap.lotto = lotti[indexPath.section].nome
        openTap.settore = settore.nome
        
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        formatter.locale = Locale(identifier: "en_US_POSIX")
        
        let date = formatter.date(from: settore.data)
        if (Locale.current.languageCode! == "it") {
            formatter.dateFormat = "dd/MM"
        } else {
            formatter.dateFormat = "MM/dd"
        }
        cell.settoreDataLabel?.text = formatter.string(from: date!)
        cell.settoreMetersLabel?.text = App.formatDecimal(value: settore.metriCubi.description,remove: true) + " mc"
        
        // Stato valvola
        
        var statoAlertTitle: String? = nil
        var statoAlertText: String? = nil
        if (settore.aperto != nil) {
            if (settore.aperto == "1") {
                statoAlertTitle = "valvstate".localized()
                statoAlertText = "valvOpen".localized()
            } else {
                statoAlertTitle = "valvstate".localized()
                statoAlertText = "valvClose".localized()
            }
        } else {
            statoAlertTitle = "valvstate".localized()
            statoAlertText = "valvSetup".localized()
        }
        
        if (statoAlertText != nil) {
            let openTap = TapGesture(target: self,action: #selector(alertTap(sender:)))
            openTap.numberOfTapsrequired = 1
            cell.settoreOpenImage.isUserInteractionEnabled = true
            cell.settoreOpenImage.addGestureRecognizer(openTap)
            openTap.title = statoAlertTitle!
            openTap.text = statoAlertText!
        }
        
        cell.settoreOpenImage.image = UIImage(named: "open")
        cell.settoreOpenImage.image = cell.settoreOpenImage.image?.withRenderingMode(.alwaystemplate)
        if (settore.aperto != nil) {
            if (settore.aperto == "1") {
                cell.settoreOpenImage.tintColor = UIColor(red: 46/255,alpha: 1)
            } else {
                cell.settoreOpenImage.tintColor = UIColor(red: 231/255,alpha: 1)
            }
        } else {
            cell.settoreOpenImage.tintColor = UIColor(red: 149/255,alpha: 1)
        }
        
        // Altri stati
        
        if (settore.salta != nil) {
            if (settore.salta == "1") {
                cell.settoreSkipImage.image = UIImage(named: "skip")
                cell.settoreSkipImage.image = cell.settoreSkipImage.image?.withRenderingMode(.alwaystemplate)
                cell.settoreSkipImage.tintColor = UIColor(red: 149/255,alpha: 1)
            }
        }
        
        var saltaAlertTitle: String? = nil
        var saltaAlertText: String? = nil
        if (settore.salta != nil) {
            if (settore.salta == "1") {
                saltaAlertTitle = "commandSkip".localized()
                saltaAlertText = "skipNext".localized()
            }
        }
        
        if (saltaAlertText != nil) {
            let openTap = TapGesture(target: self,action: #selector(alertTap(sender:)))
            openTap.numberOfTapsrequired = 1
            cell.settoreSkipImage.isUserInteractionEnabled = true
            cell.settoreSkipImage.addGestureRecognizer(openTap)
            openTap.title = saltaAlertTitle!
            openTap.text = saltaAlertText!
        }
        
        if (settore.incrementa != nil) {
            if (settore.incrementa! > 0) {
                cell.settoreIncreaseImage.image = UIImage(named: "increase")
                cell.settoreIncreaseImage.image = cell.settoreIncreaseImage.image?.withRenderingMode(.alwaystemplate)
                cell.settoreIncreaseImage.tintColor = UIColor(red: 149/255,alpha: 1)
            }
        }
        
        var maggiorazioneAlertTitle: String? = nil
        var maggiorazioneAlertText: String? = nil
        if (settore.incrementa != nil) {
            if (settore.incrementa! > 0) {
                maggiorazioneAlertTitle = "increaseTitle".localized()
                maggiorazioneAlertText = "increaseActive".localized()
            }
        }
        
        if (maggiorazioneAlertText != nil) {
            let openTap = TapGesture(target: self,action: #selector(alertTap(sender:)))
            openTap.numberOfTapsrequired = 1
            cell.settoreIncreaseImage.isUserInteractionEnabled = true
            cell.settoreIncreaseImage.addGestureRecognizer(openTap)
            openTap.title = maggiorazioneAlertTitle!
            openTap.text = maggiorazioneAlertText!
        }
        
        let defaults = UserDefaults.standard
        let automation = defaults.string(forKey: "automation")
        if (automation == "0") {
            cell.settoreCommandImage.isHidden = true
            cell.settoreOpenImage.isHidden = true
            cell.settoreSkipImage.isHidden = true
            cell.settoreIncreaseImage.isHidden = true
        }
        
        return cell
    }
    
    @objc func alertTap(sender: TapGesture) {
        // ...
    }
    
    override func tableView(_ tableView: UITableView,titleForHeaderInSection section: Int) -> String? {
        return lotti[section].nome
    }
    
    override func tableView(_ tableView: UITableView,heightForHeaderInSection section: Int) -> CGFloat {
        return 40
    }
    
    override func tableView(_ tableView: UITableView,heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 44
    }
    
    override func tableView(_ tableView: UITableView,estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
    
    override func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
        return lotti[section].settori.count
    }
    
    override func numberOfSections(in tableView: UITableView) -> Int {
        return lotti.count
    }
    
    override func tableView(_ tableView: UITableView,didSelectRowAt indexPath: IndexPath) {
        // ...
    }
    
    override func tableView(_ tableView: UITableView,viewForHeaderInSection section: Int) -> UIView? {
        let cell = lottoTableView.dequeueReusableCell(withIdentifier: "customLottoCell") as! LottoCell
        
        let lottoSection = lotti[section]
        cell.lottoNameLabel?.text = lottoSection.nome
        
        let openTap = ShowActions(target: self,action: #selector(lottodisplayActionSheet(sender:)))
        openTap.numberOfTapsrequired = 1
        cell.lottoCommandImage.isUserInteractionEnabled = true
        cell.lottoCommandImage.addGestureRecognizer(openTap)
        openTap.buttons = ["MA","AM"]
        openTap.buttons_name = ["commandManual".localized(),"commandAuto".localized(),"commandSkip".localized(),"commandDenySkip".localized(),"commandIncrease".localized(),"commandDenyIncrease".localized()]
        openTap.lotto = lottoSection.nome
        openTap.settore = nil
        
        let defaults = UserDefaults.standard
        let automation = defaults.string(forKey: "automation")
        if (automation == "0") {
            cell.lottoCommandImage.isHidden = true
        }
        
        return cell
    }
    
    func sendCommand(command: String,lotto: String,settore: String?,millimeters: String?,percentage: String?,cycles: String?) {
        // ...
    }
}

class TapGesture: UITapGestureRecognizer {
    var title = String()
    var text = String()
}

class ShowActions: UITapGestureRecognizer {
    var buttons: [String] = []
    var buttons_name: [String] = []
    var lotto: String = ""
    var settore: String? = nil
}

它仅在真实设备中发生,在模拟器中工作正常。

有什么主意吗?

非常感谢。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)