【问题标题】:Accessing an Object (SQLite table) from another ViewController Swift 4从另一个 ViewController Swift 4 访问对象(SQLite 表)
【发布时间】:2018-12-24 03:27:07
【问题描述】:

我是 swift 新手,我想要做的是返回表中的指定列以显示在单独的视图控制器中。我已经使用 SQLite.swift 定义了一个函数,它以数组的形式返回它们,就像我希望它们那样。 (在同一个视图控制器中调用时有效)

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
}

但是当我从另一个视图控制器调用该函数时,由于它试图解开一个 nil 值,我得到了一个致命错误。

var clothes = ViewController().returncolumns()

我收集到的是,由于我是在没有表格的情况下从视图控制器调用函数,所以它无法获得所需的信息。

这是第一个视图控制器中的数据库

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)
    }
}

那么我应该尝试组合视图控制器以使其全部可访问吗?或者将衣柜实例化到另一个类?或者我可以对函数调用进行一个很好的简单添加,以允许访问表。

谢谢!

第二个视图控制器:

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
}
}

这是第一个视图控制器调用

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 语句,因为在这种情况下,目标视图控制器是导航控制器,而不是存储衣服数组的 WardrobeTableViewController。当我运行调试器时,我看到它传递信息和分配的衣服数组。但在那之前它仍然消失了。

在导航控制器和 WardrobeTableViewController 之间有一个表格视图控制器,它有几个单元格,当第一个被选中时,它会打开 WardrobeTableViewController。

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

【问题讨论】:

    标签: ios swift xcode sqlite sqlite.swift


    【解决方案1】:

    编辑 2:您没有设置执行 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 中设置 衣服 返回列()

    如果是这样,您可能希望在 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()
            }
        }
    }
    

    【讨论】:

    • 嗨,我想我已经很接近了。我在调试器中看到它正在为第二个视图控制器中的衣服数组分配正确的值。问题是,一旦我离开第一个控制器并转到第二个,数组现在是空的。我不知道为什么它空了
    • 我添加了它。这很简单。我正在阅读它可能与导航控制器有关导致先前的值取消分配?但我不太确定
    • 查看我的编辑,如果一切设置正确,您唯一错过的就是在设置数组后重新加载表
    • 衣服变量的第二个设置显示无效的重新声明。如果我注释掉该行,一旦到达第二个视图控制器,我仍然会看到一个空数组
    • 是的,它是旧答案的一部分。如果您分享有关如何执行 segue 和准备的代码,也许我们可以弄清楚
    猜你喜欢
    • 2020-11-04
    • 1970-01-01
    • 1970-01-01
    • 2015-06-16
    • 1970-01-01
    • 1970-01-01
    • 2013-09-23
    • 2014-10-18
    • 1970-01-01
    相关资源
    最近更新 更多