Arrays 从结构填充UITableview

Arrays 从结构填充UITableview,arrays,swift,variables,struct,Arrays,Swift,Variables,Struct,我有两个ViewController,一个叫做programlist,它显示平铺列表并填充合适的视图 第二个viewController输入数据。由于prepareForsegue函数中的错误,在实现回调时出现问题。获取错误“实例成员'callback'不能用于'addWorkout'类型” viewController 1又名程序列表: import UIKit struct Item: Codable { var title: String var others: [String] }

我有两个ViewController,一个叫做programlist,它显示平铺列表并填充合适的视图

第二个viewController输入数据。由于
prepareForsegue
函数中的错误,在实现回调时出现问题。获取错误“实例成员'callback'不能用于'addWorkout'类型”

viewController 1又名程序列表:

import UIKit

struct Item: Codable {
var title: String
var others: [String]
}

class ProgramList: UIViewController, UITableViewDataSource, UITableViewDelegate{

var Programs = [Item]()

@IBOutlet weak var programTableView: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()
    load()
}

//saving current state of programs array
func save() {
    guard let data = try? JSONEncoder().encode(Programs) else { return }
    UserDefaults.standard.set(data, forKey: "notes")
}

//loading saved program array
func load() {
    guard let loadedData = UserDefaults.standard.data(forKey: "notes")  else { return }
    do {
        Programs = try JSONDecoder().decode([Item].self, from: loadedData)
        programTableView.reloadData()
    } catch { print(error) }
}






func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return Programs.count
}


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
              cell.programTitle.text = Programs[indexPath.row].title
    return cell
}

//Removing Item by swipping left & saving this newly established array
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {

    if editingStyle == UITableViewCell.EditingStyle.delete {
        Programs.remove(at: indexPath.row)
        programTableView.reloadData()
        save()
    }


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

        if segue.identifier == "toAddPage"{
            workoutController.callback = { [weak self] string in
                let entered = Item(title: string, others: ["hi"])
                self?.programs.append(entered)
                let indexPath = IndexPath(row: self?.programs.count - 1, section: 0)
                self?.tableView.insertRows(at: [indexPath], with: .automatic)
                self?.save()
         }
       }
    }    
  }
}

  }
viewController 2运动计划:

 import UIKit

 class addWorkout: UIViewController {

@IBOutlet weak var workoutTitle: UITextField!

var callback : ((String) -> Void)?

override func viewDidLoad() {
    super.viewDidLoad()
}

@IBAction func saveWorkoutTitle(_ sender: Any) {

    if !workoutTitle.text!.isEmpty {
        callback?(workoutTitle.text!)
    }   
}
}

主要错误是您试图将
项的数组
保存到
用户默认值
,并读取
字符串的数组
。这是一个明显的类型不匹配

要能够将自定义结构的数组保存到
UserDefaults
中,请采用
Codable
将结构保存为JSON

struct Item : Codable {
    var title: String
    var others: [String]
}
此外,在任何类之外声明数据源数组是一种非常糟糕的做法

这是
ProgramList
类,具有调整后的
load
save
方法以及类内的数据源数组。不需要方法
viewdide

class ProgramList: UIViewController, UITableViewDataSource, UITableViewDelegate {
    @IBOutlet weak var programTableView: UITableView!

    var programs = [Item]()

    override func viewDidLoad() {
        super.viewDidLoad()
        load()
    }

    //saving current state of programs array
    func save() {
        guard let data = try? JSONEncoder().encode(programs) else { return }
        UserDefaults.standard.set(data, forKey: "notes")
    }

    //loading saved program array
    func load() {
        guard let loadedData = UserDefaults.standard.data(forKey: "notes")  else { return }
        do {
            programs = try JSONDecoder().decode([Item].self, from: loadedData)
            programTableView.reloadData()
        } catch { print(error) }
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return programs.count
    }


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
        cell.programTitle.text = programs[indexPath.row].title
        return cell
    }

    //Removing Item by swipping left & saving this newly established array
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            programs.remove(at: indexPath.row)
            programTableView.deleteRows(at: [indexPath], with: .automatic)
            save()
        }
    }
}
要在控制器之间共享数据,请使用闭包作为回调并传递字符串

class AddWorkout: UIViewController {

    @IBOutlet weak var workoutTitle: UITextField!

    var callback : ((String) -> Void)?

    @IBAction func saveWorkoutTitle(_ sender: Any) {
        if !workoutTitle.text!.isEmpty {
            callback?(workoutTitle.text!)
        }
    }
}
回到
ProgramList
controller为
prepareforsgue
中的
callback
属性分配一个闭包(或在显示控制器之前)


显示其余代码:完整的
cellForRowAt
、任何UITableCell覆盖、数据源方法……请向我们显示表视图数据源方法。请共享剩余代码。请使用适当的方式提问并尝试学习自己的方法。我已经更新了代码好的,就在最后一节,我将
workoutController.callback
更改为
addWorkout.callback
,因为这是我添加了训练细节的swift文件的名称。但是,我得到一个错误,即nstance成员“callback”不能用于类型“addWorkout”。我在
prepareForSegue
函数中有这个。请编辑您的问题并添加
prepareForSegue
。并再次根据命名约定以大写字母开头命名类。这可以避免这些错误,因为您可以立即看到类型和实例。已编辑问题并添加了
prepareforsgue
。很抱歉命名约定。我将在实际代码中对此进行修改。请查看更新的答案。不要编辑问题并添加部分解决方案。这将使其他读者感到困惑。
 func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if segue.identifier == "toAddPage" {
        let workoutController = segue.destination as! AddWorkout
        workoutController.callback = { string in
            let entered = Item(title: string, others: ["hi"])
            self.programs.append(entered)
            let indexPath = IndexPath(row: self.programs.count - 1, section: 0)
            self.tableView.insertRows(at: [indexPath], with: .automatic)
            self.save()
        }
    }
}