从另一个 ViewController Swift 4 访问对象 (SQLite table)

Accessing an Object (SQLite table) from another ViewController Swift 4

我是 swift 的新手,我想做的是 return 我的 table 中的指定列显示在单独的 viewcontroller 中。我已经使用 SQLite.swift 定义了一个函数,将它们 return 放在一个数组中,就像我希望的那样。 (在同一个 viewcontroller 中调用时有效)

func returncolumns() -> Array<String> {
    print("RETURNING")
    var namearray = [String]()
    do {
        for wardrobe in try wardrobedb.prepare(wardrobe.select(name)) {
            namearray.append(wardrobe[name])
        }
    } catch {
        print("This no worko \(error)")
    }
    return namearray
}

但是当我从另一个 viewcontroller 调用该函数时,由于它试图解包 nil 值而出现致命错误。

var clothes = ViewController().returncolumns()

我收集到的是,由于我在没有 table 的情况下从 viewcontroller 调用函数,它无法获得所需的信息。

这里是第一个viewcontroller

的数据库
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

var wardrobedb: Connection!

let wardrobe = Table("wardrobe")

let id = Expression<Int64>("id")
let name = Expression<String>("name")
let type = Expression<String>("type")
let color = Expression<String>("color")
let style = Expression<String>("style")
let weight = Expression<String>("weight")
let pattern = Expression<String>("pattern")

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    do {
        let documentDirectory = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
        let fileUrl = documentDirectory.appendingPathComponent("wardrobe").appendingPathExtension("sqlite3")
        let wardrobedb = try Connection(fileUrl.path)
     //   let wardrobedb = try remove(fileUrl.path)
        self.wardrobedb = wardrobedb
    } catch {
        print(error)
    }
}

那么我是否应该尝试组合视图控制器以便它都可以访问?或者将衣橱实例移到另一个 class?或者我可以对函数调用进行一个很好的简单添加,这将允许访问 table。

谢谢!

第二个ViewController:

import UIKit

class WardrobeTableViewController: UITableViewController {

var clothes = [String]()

// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

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

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return "Section \(section)"
}

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

    let clothesname = clothes[indexPath.row]
    cell.textLabel?.text = clothes[indexPath.row]
    cell.detailTextLabel?.text = "Very cool!"
//    cell.imageView?.image = UIImage(named: clothesname)

    return cell
}
}

这是第一个viewcontroller调用

func returncolumns() -> Array<String> {
    print("RETURNING")
    var namearray = [String]()
    do {
        for wardrobe in try wardrobedb.prepare(wardrobe.select(name)) {
            namearray.append(wardrobe[name])
        }
    } catch {
        print("This no worko \(error)")
    }
    return namearray
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "wardrobemove" {
      //  if let destinationVC = segue.destination as? WardrobeTableViewController {
            WardrobeTableViewController().clothes = returncolumns()
      ///  }
    }
}

所以在这里我将 "wardrobemove" 识别为移入导航控制器的 segue。我注释掉了 if 语句,因为在这种情况下,目的地 viewcontroller 是导航控制器,而不是存储衣服数组的 WardrobeTableViewController。当我 运行 调试器时,我看到它传递信息和正在分配的衣服数组。但在那之前它仍然消失了。

在导航控制器和衣柜之间TableViewController有一个 Table 视图控制器,它有几个单元格,当第一个被选中时,它打开衣柜TableViewController.

这有点乱,我遵循了两个指南,我认为第二个引入导航控制器的指南有点乱。

编辑 2:你没有设置 class 实例的衣服 属性 执行 segue(但你设置了一个新的实例)。改成这样:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    //check if the performed segue has "wardrobemove" id
    if segue.identifier == "wardrobemove" {
        //check if the destination is kind of WardrobeTableViewController
        if let destinationVC = segue.destination as? WardrobeTableViewController {
            //if it is so, then set its property clothes
            destinationVC.clothes = returncolumns()
      }
   }
}

编辑

在你的第二个 vc 中,你想在每次设置衣服数组时重新加载你的 tableView:

var clothes = [String]() {
    didSet {
        self.tableView.reloadData()
    }
}

旧答案

var clothes = ViewController().returncolumns()

您的 FirstVC 中包含所有内容,并且您想在 SecondVC 中设置 衣服基于方法返回的值 returncolumns()

如果是这样,您可能希望在 FirstVC 和 SecondVC 之间执行 segue,并执行 prepareForSegue 来设置衣服。类似于:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "segueIdentifier" {
        if let destinationVC = segue.destination as? SecondViewController {
            destinationVC.clothes = returncolumns()
        }
    }
}