ios - reloaddata() 函数关闭 tableview,并返回到上一个屏幕

标签 ios swift

我有一个带有两个屏幕( View Controller 和表格 View )的应用程序,每次用户更新数据上使用的过滤器时,我都会尝试在表格 View 中重新加载数据。例如,我的数组保存火车时刻表数据,我根据方向过滤这些数据。用户更新方向,然后 TableView 应重新加载并更新方向过滤器。

我尝试过使用 DispatchQueue.main.async { self.tableView.reloadData() }

我有一个由按钮操作调用的函数来更新方向

@IBAction func ChangeDirection(_ sender: Any) {
    changeDirection()
}

func changeDirection()
{
    if direction == "Southbound" {
        direction = "Northbound"
    }
    else {
        direction = "Southbound"
    }

    DispatchQueue.main.async { self.tableView.reloadData() }
}

我使用带有 ui 选择器的 View Controller ,以便用户可以选择他们想要的火车时刻表的车站,ui 选择器访问一个单例类,该类保存每个车站的火车计划数据(我想知道这是否可能是问题)也许这需要从 TableView 访问。

if segue.identifier == "Stations"
    {
        let vc = segue.destination as? TableViewController
        let xmlParserSchedule = XMLParserSchedule()
        xmlParserSchedule.runScheudledParser(userStation:StationsDecoder.shared.uiStationsSorted[station])
        vc?.stationData=xmlParserSchedule.sortedArrival


    }

我希望 tableview 根据用户选择的新方向重新加载,但是 tableview 已关闭,我们返回到 View Controller ui 选择器屏幕。当我在调用 reloaddata() 时调试代码时,我注意到内存似乎无限泄漏。

我正在添加来自 View Controller 和 TableView 的完整代码,以防万一这有帮助:

View Controller : 导入 UIKit

@available(iOS 9.0, *)

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

    //stores picker selection for array index in station data
    var station = 0
    //UI Picker Outlet
    @IBOutlet weak var UIStationPicker: UIPickerView!



    override func viewDidLoad() {
        super.viewDidLoad()
        //self.UIStationPicker.setValue(UIColor.white, forKey: "textColor")
        self.UIStationPicker.delegate = self
        self.UIStationPicker.dataSource = self
        self.UIStationPicker.reloadAllComponents()

        //check if station file is already loaded by accessing the singletons/create plist throw method
        do {
            try? CreatePlist.shared.createPlist()
            //throw needed here to reach the catch block
            throw CreatePlist.ErrorsToThrow.fileAlreadyExists
        }catch {
            print("file already exists")
            print("time to get decoding")
            //decode the station plist using singleton class method
            StationsDecoder.shared.decoder()
            //get stations in array of dictionaries using singlton class method
            StationsDecoder.shared.getStations()
            self.UIStationPicker.reloadAllComponents()

        }
    }
    //uiPicker delegate methods
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Number of columns of data
    }
    func numberOfComponents(in pickerView: UIPickerView) ->Int {
        return 1
    }
    // The number of rows of data
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int)-> Int {
        return StationsDecoder.shared.uiStationsSorted.count
    }
    // The data to return for the row and component (column) that's being passed in
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int)-> String? {

        return StationsDecoder.shared.uiStationsSorted[row]
    }


    func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
        let titleData = StationsDecoder.shared.uiStationsSorted[row]
        let myTitle = NSAttributedString(string: titleData, attributes: [NSAttributedString.Key.font:UIFont(name: "Georgia", size: 28.0)!,NSAttributedString.Key.foregroundColor:UIColor.white])
        return myTitle
    }
    // Capture the picker view selection
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

        station = row

        performSegue(withIdentifier: "Stations", sender: Any?.self)

    }


    override func prepare(for segue: UIStoryboardSegue, sender: Any?){


    if segue.identifier == "Stations"
    {
        let vc = segue.destination as? TableViewController
        let xmlParserSchedule = XMLParserSchedule()
        xmlParserSchedule.runScheudledParser(userStation:StationsDecoder.shared.uiStationsSorted[station])
        vc?.stationData=xmlParserSchedule.sortedArrival


    }
        }



}

表格 View

import UIKit

var direction:String = "Southbound"


class TableViewController: UITableViewController{

//this code here is interesting, it dismisses the presented view with orignally presented view ie tableview is replaced with initial view controller. this avoids calling dataload method again in view controller which can duplicate your data

@IBAction func GoBack(_ sender: Any) {
        dismiss(animated: true, completion: nil)
}

@IBAction func ChangeDirection(_ sender: Any) {
    changeDirection()
}

func changeDirection()
{
    if direction == "Southbound" {
        direction = "Northbound"
    }
    else {
        direction = "Southbound"
    }

    DispatchQueue.main.async { self.tableView.reloadData() }
}

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.delegate = self
    tableView.dataSource = self

}

//array of tuples to hold station data
var stationData: [(stationfullname:String,origin: String,destination:String,lastLocation: String, dueIn: Int, late: Int, due: Int, expArrival: String, direction: String) ] = []

//array literal, for tuples
//var data = [String:(stationfullname:String,origin: String,destination:String,lastLocation: String, dueIn: Int, late: Int, due: Int, expArrival: String, direction: String)].self



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

// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
    // As long as `total` is the last case in our TableSection enum,
    // this method will always be dynamically correct no mater how many table sections we add or remove.
      return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows

            return stationData.filter{($0.direction == direction)}.count
}

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

         return direction

}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "StationLevel", for: indexPath)
           cell.textLabel?.text = stationData.filter{($0.direction == direction)}[indexPath.row].destination
            cell.detailTextLabel?.text = "\(String(stationData.filter{($0.direction == direction)}[indexPath.row].due)) mins"

    return cell
}

}

最佳答案

哦,Lordie,原来我有一个额外的发送事件用于发送回 View Controller 的按钮,有 4 个小时我永远不会回来。 不管帕尔文如何,感谢您的帮助。

关于ios - reloaddata() 函数关闭 tableview,并返回到上一个屏幕,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58453638/

相关文章:

ios - 使用 Alamofire 时将 JSON 数据放入数组

objective-c - 自定义 UITableViewController 单元格 segue 不推送

ios - 全局变量总是保留在内存中吗?

ios - 添加应用程序组功能后清空授权文件

ios - iOS/macOS云共享相册中如何给照片附加短数据?

swift - 如何使用大量初始化程序快速创建自定义 UIView 类?

swift - 如何在 Swift 5.0 中通过 CAShapeLayer 以点开始和结束一行

ios - 当应用程序处于后台时如何在 didReceiveRemoteNotification 上打开特定的 View Controller

ios - 迭代NSMutableArray时,如何删除一个对象然后插入多个对象?

ios - Swift 二维数组最小值