Swift 3 - 从核心数据中获取价值
Posted
技术标签:
【中文标题】Swift 3 - 从核心数据中获取价值【英文标题】:Swift 3 - Get value from core data 【发布时间】:2018-02-20 22:57:02 【问题描述】:我有一个需要 2 个输入的类,Sets 和 Reps
使用 prepare(for segue: UIStoryboardSegue, sender: Any?) 我将值传递回 WorkoutViewController.Swift
数据保存成功,因为在 SetRepsViewController.Swift 中按下保存栏按钮后弹出窗口
但是标签不显示值 我在这里做错了什么 我相信 targetLog?.setAndrep?.sets 没有正确获得价值
有人可以帮我解决我应该怎么做吗?
viewController的屏幕截图
WorkoutViewController.swift
import UIKit
import CoreData
class WorkoutViewController: UIViewController
var muscleLog: MuscleList?
var targetLog: Log?
@IBOutlet weak var LogTableView: UITableView!
@IBOutlet weak var input: UITextField!
@IBOutlet weak var weightInput: UITextField!
@IBOutlet weak var repsInput: UITextField!
@IBOutlet weak var dateView: UILabel!
@IBOutlet weak var setsLabel: UILabel!
@IBOutlet weak var repsLabel: UILabel!
let dateFormatter = DateFormatter()
func workoutTitle(title: String)
self.title = title
override func viewDidLoad()
super.viewDidLoad()
dateFormatter.calendar = Calendar(identifier: .persian)
dateFormatter.dateFormat = "dd/MM/yyyy"
let date = Date()
let dateInPersian = dateFormatter.string(from: date)
dateView.text = dateInPersian
override func viewWillAppear(_ animated: Bool)
setsLabel.text = targetLog?.repLog?.sets
repsLabel.text = targetLog?.setAndrep?.reps
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
if segue.identifier == "addTarget"
guard let destination = segue.destination as? SetRepsViewController else
return
destination.destLog = targetLog
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
//hide keybaord method
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
self.view.endEditing(true)
@IBAction func addLog(_ sender: Any)
let weight = Double(weightInput.text ?? "") ?? 0.0
let reps = Int16(repsInput.text ?? "") ?? 0
let todayDate = dateView.text ?? ""
let notes = input.text ?? ""
if let log = Log(weight: weight, reps: reps, currentday: todayDate, notes: notes)
muscleLog?.addToDailyLogs(log)
do
try log.managedObjectContext?.save()
catch
print("Could not Log")
LogTableView.reloadData()
func deleteMuscle(at indexPath: IndexPath)
guard let logs = muscleLog?.logList?[indexPath.row],
let managedContext = logs.managedObjectContext else
return
managedContext.delete(logs)
do
try managedContext.save()
LogTableView.deleteRows(at: [indexPath], with: .automatic)
catch
print("Could not save")
LogTableView.reloadRows(at: [indexPath], with: .automatic)
extension WorkoutViewController: UITableViewDelegate,UITableViewDataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return muscleLog?.logList?.count ?? 0
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let WorkCell = LogTableView.dequeueReusableCell(withIdentifier: "WorkCell", for: indexPath)
if let logs = muscleLog?.logList?[indexPath.row]
WorkCell.textLabel?.text = logs.currentday
let weight = String(logs.weight)
let reps = String(logs.reps)
let note = logs.notes
WorkCell.detailTextLabel?.text = weight + " kg x " + reps + " reps Notes: "+note!
return WorkCell
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
if editingStyle == .delete
deleteMuscle(at: indexPath)
SetRepsViewController.swift
import UIKit
class SetRepsViewController: UIViewController
var destLog: Log?
@IBOutlet weak var setText: UITextField!
@IBOutlet weak var repText: UITextField!
@IBAction func saveTarget(_ sender: UIBarButtonItem)
let sets = setText.text ?? ""
let reps = repText.text ?? ""
if let target = SetRep(sets: sets, reps: reps)
destLog?.addsetAndrep(target)
do
try target.managedObjectContext?.save()
self.navigationController?.popViewController(animated: true)
catch
print("Could not save workout")
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view.
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
【问题讨论】:
你应该在viewWillAppear
而不是viewDidLoad
中设置标签。
@pbasdf 我也把它放在 viewWillApear 中,但没有用
destLog
和 targetLog
是如何声明和填充的?
@pbasdf 使用 prepare for segue 函数覆盖 func prepare(for segue: UIStoryboardSegue, sender: Any?) if segue.identifier == "addTarget" guard let destination = segue.destination as? SetRepsViewController else return destination.destLog = targetLog
targetLog == nil 吗?你是怎么设置的?
【参考方案1】:
@IMan 将数据保存到核心数据后,您必须从 CoreData 获取数据,然后才能显示您的数据。
【讨论】:
你知道我如何获取数据吗,我尝试了很多方法,我不确定如何获取一对一关系的数据【参考方案2】:您需要在您的prepareForSegue
中设置destLog
的值,方法是确定在tableView 中选择了哪一行:
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
if segue.identifier == "addTarget"
guard let destination = segue.destination as? SetRepsViewController else
return
let indexPath = LogTableView.indexPathForSelectedRow
targetLog = muscleLog?.logList?[indexPath.row]
destination.destLog = targetLog
这将确保与表视图中选定行对应的 Log 传递给 SetRepsViewController。当您关闭 SetRepsViewController 时,viewWillAppear
代码将正确更新标签,因为 targetLog
和 destLog
都引用同一个 Log 对象。
【讨论】:
它给出了线程 1:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) segue 连接到场景中的哪个元素?我以为它是原型细胞?【参考方案3】:@IMan 试试这个
func fetchList()
let moc = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let fetchRequest: NSFetchRequest<"YOUR ENTITY NAME"> = ("YOUR ENTITY NAME").fetchRequest()
do
let fetchResults = try self.moc.fetch(fetchRequest)
for Entity in fetchResults as [NSManagedObject]
let entity1 = Entity.value(forKey: "YOUR ENTITY KEY VALUE")
let entity12 = Entity.value(forKey: "YOUR ENTITY KEY VALUE")
print(entity1, entity2)
catch
print(error.localizedDescription)
【讨论】:
以上是关于Swift 3 - 从核心数据中获取价值的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Firebase 数据库中的 autoID 获取价值 - Swift