这是我的代码:
import UIKit
import CoreData
class ExerciseViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
//sets stepper configs
setsStepper.wraps = false
setsStepper.autorepeat = true
setsStepper.continuous = true
setsStepper.tintColor = UIColor.redColor()
setsStepper.minimumValue = 0
setsStepper.maximumValue = 500
setsStepper.value = 0
//reps stepper configs
repsStepper.wraps = false
repsStepper.autorepeat = true
repsStepper.continuous = true
repsStepper.tintColor = UIColor.orangeColor()
repsStepper.minimumValue = 0
repsStepper.maximumValue = 500
repsStepper.value = 0
exerciseTableView.reloadData()
}
var moc = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
var fetchedResultsController: NSFetchedResultsController?
@IBOutlet var exerciseTableView: UITableView!
@IBOutlet var dayName: UITextField!
@IBOutlet var exerciseName: UITextField!
@IBOutlet var setsStepper: UIStepper!
@IBOutlet var repsStepper: UIStepper!
@IBOutlet var setsNumber: UILabel!
@IBOutlet var repsNumber: UILabel!
var daysArray = [String]()
var namesArray = [String]()
var setsArray = [Int]()
var repsArray = [Int]()
func appendDaysToArray() {
let dayLabel = dayName.text
daysArray.append(dayLabel)
let entityDescription = NSEntityDescription.entityForName("TrainingDay", inManagedObjectContext: moc!)
let trainingday = TrainingDay(entity: entityDescription!, insertIntoManagedObjectContext: moc)
trainingday.day = dayName.text
var error: NSError?
moc?.save(&error)
if let err = error {
var status = err.localizedFailureReason
println("\(status)")
} else {
println("Day #\(dayName.text) saved successfully!")
}
}
func appendNamesToArray () {
let nameLabel = exerciseName.text
namesArray.append(nameLabel)
let entityDescription = NSEntityDescription.entityForName("TrainingDetails", inManagedObjectContext: moc!)
let trainingdetails = TrainingDetails(entity: entityDescription!, insertIntoManagedObjectContext: moc)
trainingdetails.exerciseName = exerciseName.text
var error: NSError?
moc?.save(&error)
if let err = error {
var status = err.localizedFailureReason
println("\(status)")
} else {
println("Exercise: #\(exerciseName.text) saved successfully!")
}
}
func appendNumberToSets () {
let numberOfSets = setsNumber.text?.toInt()
setsArray.append(numberOfSets!)
let entityDescription = NSEntityDescription.entityForName("TrainingDetails", inManagedObjectContext: moc!)
let trainingdetails = TrainingDetails(entity: entityDescription!, insertIntoManagedObjectContext: moc)
trainingdetails.setsNumber = setsNumber.text!
var error: NSError?
moc?.save(&error)
if let err = error {
var status = err.localizedFailureReason
println("\(status)")
} else {
println("Exercise: #\(setsNumber.text) saved successfully!")
}
}
func appendNumberOfReps () {
let numberOfReps = repsNumber.text?.toInt()
repsArray.append(numberOfReps!)
let entityDescription = NSEntityDescription.entityForName("TrainingDetails", inManagedObjectContext: moc!)
let trainingdetails = TrainingDetails(entity: entityDescription!, insertIntoManagedObjectContext: moc)
trainingdetails.repsNumber = repsNumber.text!
var error: NSError?
moc?.save(&error)
if let err = error {
var status = err.localizedFailureReason
println("\(status)")
} else {
println("Exercise: #\(repsNumber.text) saved successfully!")
}
}
@IBAction func doneButton(sender: AnyObject) {
println("\(dayName.text)")
appendDaysToArray()
println("\(exerciseName.text)")
appendNamesToArray()
println("\(setsNumber.text)")
appendNumberToSets()
println("\(repsNumber.text)")
appendNumberOfReps()
exerciseTableView.reloadData()
}
@IBAction func setsStepperAction(sender: UIStepper) {
println("\(Int(sender.value))")
setsNumber.text = Int(sender.value).description
}
@IBAction func repsStepper(sender: UIStepper) {
println("\(Int(sender.value))")
repsNumber.text = Int(sender.value).description
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return namesArray.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "exerciseCell"
var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? UITableViewCell
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Value2, reuseIdentifier: cellIdentifier)
}
let row = indexPath.row
let name = namesArray[indexPath.row]
let numberReps = repsArray[indexPath.row]
let numberSets = setsArray[indexPath.row]
cell!.textLabel!.text = name
cell?.detailTextLabel?.text = "Sets: #\(numberSets) Reps: #\(numberReps)"
return cell!
}
}
和
class ViewExercisesViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate {
override func viewDidLoad() {
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchTrainingDetails(), managedObjectContext: moc!, sectionNameKeyPath: nil, cacheName: nil)
fetchedResultsController?.delegate = self
fetchedResultsController?.performFetch(nil)
self.viewExerciseTableView.reloadData()
sundayButton.frame = CGRectMake(-30,150,125,125)
sundayButton.addTarget(self, action: "sundayButtonTouch:", forControlEvents: UIControlEvents.TouchDown)
sundayButton.setImage(imageSunday, forState: .Normal)
sundayButton.imageEdgeInsets = UIEdgeInsetsMake(30,30,30,30)
self.view.addSubview(sundayButton)
mondayButton.frame = CGRectMake(120,150,125,125)
mondayButton.addTarget(self, action: "mondayButtonTouch:", forControlEvents: UIControlEvents.TouchDown)
mondayButton.setImage(imageMonday, forState: .Normal)
mondayButton.imageEdgeInsets = UIEdgeInsetsMake(30,30,30,30)
self.view.addSubview(mondayButton)
tuesdayButton.frame = CGRectMake(270,150,125,125)
tuesdayButton.addTarget(self, action: "tuesdayButtonTouch:", forControlEvents: UIControlEvents.TouchDown)
tuesdayButton.setImage(imageTuesday, forState: .Normal)
tuesdayButton.imageEdgeInsets = UIEdgeInsetsMake(30,30,30,30)
self.view.addSubview(tuesdayButton)
wednesdayButton.frame = CGRectMake(-30,250,125,125)
wednesdayButton.addTarget(self, action: "wednesdayButtonTouch:", forControlEvents: UIControlEvents.TouchDown)
wednesdayButton.setImage(imageWednesday, forState: .Normal)
wednesdayButton.imageEdgeInsets = UIEdgeInsetsMake(30,30,30,30)
self.view.addSubview(wednesdayButton)
thursdayButton.frame = CGRectMake(70,250,125,125)
thursdayButton.addTarget(self, action: "thursdayButtonTouch:", forControlEvents: UIControlEvents.TouchDown)
thursdayButton.setImage(imageThursday, forState: .Normal)
thursdayButton.imageEdgeInsets = UIEdgeInsetsMake(30,30,30,30)
self.view.addSubview(thursdayButton)
fridayButton.frame = CGRectMake(170,250,125,125)
fridayButton.addTarget(self, action: "fridayButtonTouch:", forControlEvents: UIControlEvents.TouchDown)
fridayButton.setImage(imageFriday, forState: .Normal)
fridayButton.imageEdgeInsets = UIEdgeInsetsMake(30,30,30,30)
self.view.addSubview(fridayButton)
saturdayButton.frame = CGRectMake(270,250,125,125)
saturdayButton.addTarget(self, action: "saturdayButtonTouch:", forControlEvents: UIControlEvents.TouchDown)
saturdayButton.setImage(imageSaturday, forState: .Normal)
saturdayButton.imageEdgeInsets = UIEdgeInsetsMake(30,30,30,30)
self.view.addSubview(saturdayButton)
}
//VAR AND LET
var sundayButton = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton
var imageSunday = UIImage(named: "day.png")
var mondayButton = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton
var imageMonday = UIImage(named: "day.png")
var tuesdayButton = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton
var imageTuesday = UIImage(named: "day.png")
var wednesdayButton = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton
var imageWednesday = UIImage(named: "day.png")
var thursdayButton = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton
var imageThursday = UIImage(named: "day.png")
var fridayButton = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton
var imageFriday = UIImage(named: "day.png")
var saturdayButton = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton
var imageSaturday = UIImage(named: "day.png")
@IBOutlet var viewExerciseTableView: UITableView!
var moc = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
var fetchedResultsController: NSFetchedResultsController?
// FUNCTIONS
func sundayButtonTouch(sender: UIButton!) {
println("future event will be added, button working fine - sunday")
}
func mondayButtonTouch(sender: UIButton!) {
println("future event will be added, button working fine - monday")
}
func tuesdayButtonTouch(sender: UIButton!) {
println("future event will be added, button working fine - tuesday")
}
func wednesdayButtonTouch(sender: UIButton!) {
println("future event will be added, button working fine - wednesday")
}
func thursdayButtonTouch(sender: UIButton!) {
println("future event will be added, button working fine - thursday")
}
func fridayButtonTouch(sender: UIButton!) {
println("future event will be added, button working fine - friday")
}
func saturdayButtonTouch(sender: UIButton!) {
println("future event will be added, button working fine - saturday")
}
// FETCH REQUEST METHODS
func fetchTrainingDay() -> NSFetchRequest {
let fetchRequest = NSFetchRequest(entityName: "TrainingDay")
// let predicate = NSPredicate(format: "day == %@")
let sortDescriptor = NSSortDescriptor(key: "day", ascending: true)
fetchRequest.predicate = nil
fetchRequest.sortDescriptors = [sortDescriptor]
fetchRequest.fetchBatchSize = 20
return fetchRequest
}
func fetchTrainingDetails() -> NSFetchRequest {
let fetchRequest = NSFetchRequest(entityName: "TrainingDetails")
fetchRequest.predicate = nil
let sortDescriptor1 = NSSortDescriptor(key: "exerciseName", ascending: true)
let sortDescriptor2 = NSSortDescriptor(key: "repsNumber", ascending: true)
let sortDescriptor3 = NSSortDescriptor(key: "setsNumber", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor1, sortDescriptor2, sortDescriptor3]
fetchRequest.fetchBatchSize = 20
return fetchRequest
}
//TABLE VIEW DELEGATE METHODS
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return fetchedResultsController?.sections?[section].numberOfObjects ?? 0
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "exCell"
var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? UITableViewCell
if let exCell = fetchedResultsController?.objectAtIndexPath(indexPath) as? TrainingDetails {
println("THE ERROR IS HERE #\(exCell.exerciseName) \(exCell.repsNumber) \(exCell.setsNumber)")
cell!.textLabel?.text = exCell.exerciseName
cell?.detailTextLabel?.text = "Sets: #\(exCell.setsNumber) Reps: #\(exCell.repsNumber)"
}
return cell!
}
// MARK: NSFetchedResultsControllerDelegate
func controllerWillChangeContent(controller: NSFetchedResultsController) {
self.viewExerciseTableView.beginUpdates()
}
func controller(controller: NSFetchedResultsController,
didChangeObject anObject: AnyObject,
atIndexPath indexPath: NSIndexPath?,
forChangeType type: NSFetchedResultsChangeType,
newIndexPath: NSIndexPath?)
{
switch(type) {
case .Insert:
if let newIndexPath = newIndexPath {
viewExerciseTableView.insertRowsAtIndexPaths([newIndexPath],
withRowAnimation:UITableViewRowAnimation.Fade)
}
case .Delete:
if let indexPath = indexPath {
viewExerciseTableView.deleteRowsAtIndexPaths([indexPath],
withRowAnimation: UITableViewRowAnimation.Fade)
}
case .Update:
break
case .Move:
if let indexPath = indexPath {
if let newIndexPath = newIndexPath {
viewExerciseTableView.deleteRowsAtIndexPaths([indexPath],
withRowAnimation: UITableViewRowAnimation.Fade)
viewExerciseTableView.insertRowsAtIndexPaths([newIndexPath],
withRowAnimation: UITableViewRowAnimation.Fade)
}
}
}
}
func controller(controller: NSFetchedResultsController,
didChangeSection sectionInfo: NSFetchedResultsSectionInfo,
atIndex sectionIndex: Int,
forChangeType type: NSFetchedResultsChangeType)
{
switch(type) {
case .Insert:
viewExerciseTableView.insertSections(NSIndexSet(index: sectionIndex),
withRowAnimation: UITableViewRowAnimation.Fade)
case .Delete:
viewExerciseTableView.deleteSections(NSIndexSet(index: sectionIndex),
withRowAnimation: UITableViewRowAnimation.Fade)
default:
break
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
viewExerciseTableView.endUpdates()
}
}
和
import Foundation
import CoreData
class TrainingDetails: NSManagedObject {
@NSManaged var exerciseName: String
@NSManaged var setsNumber: String
@NSManaged var repsNumber: String
@NSManaged var relationship2: NSManagedObject
}
逻辑是这样的:在“ExerciseViewController”中,我在CoreData中放了一些东西,这个视图运行正常。现在,在ViewExercisesViewController中,我应该检索exerciseName并将其设置为单元格的textLabel,但它在此处崩溃:println("THE ERROR IS HERE #\(exCell.exerciseName) \(exCell.repsNumber) \(exCell.setsNumber)")
。我似乎没有正确地检索它,但我确定它正在CoreData中保存。
任何人都有任何想法?我有一个类似的应用程序,但这个不起作用。
感谢您的帮助,我期待弄清楚这里有什么问题。
编辑 - >图像有挤压错误:
编辑2
导致这个:
最终编辑 - >的解
汤姆说,做到这一点:
func appendTrainingDetails () {
let nameLabel = exerciseName.text
namesArray.append(nameLabel)
let numberOfSets = setsNumber.text?.toInt()
setsArray.append(numberOfSets!)
let numberOfReps = repsNumber.text?.toInt()
repsArray.append(numberOfReps!)
let entityDescription = NSEntityDescription.entityForName("TrainingDetails", inManagedObjectContext: moc!)
let trainingdetails = TrainingDetails(entity: entityDescription!, insertIntoManagedObjectContext: moc)
trainingdetails.exerciseName = exerciseName.text
trainingdetails.setsNumber = setsNumber.text!
trainingdetails.repsNumber = repsNumber.text!
var error: NSError?
moc?.save(&error)
if let err = error {
var status = err.localizedFailureReason
println("\(status)")
} else {
println("Exercise: #\(exerciseName.text) saved successfully!")
println("Number of sets: #\(setsNumber.text) saved successfully!")
println("Number of reps: #\(repsNumber.text) saved successfully!")
}
}
用这些方法,让我解决了我做错了什么!非常感谢你!!
答案 0 :(得分:2)
这就是它的样子......
您的方法appendNumberToSets()
,appendNumberOfReps()
和appendNamesToArray()
都有此代码:
let entityDescription = NSEntityDescription.entityForName("TrainingDetails", inManagedObjectContext: moc!)
let trainingdetails = TrainingDetails(entity: entityDescription!, insertIntoManagedObjectContext: moc)
这意味着这些中的每一个都在创建TrainingDetails
的新实例。然而,
appendNumberToSets()
仅设置setsNumber
属性的值appendNamesToArray()
仅设置exerciseName
属性的值appendNumberOfReps()
仅设置repsNumber
属性的值在这三种方法中,您创建了新的TrainingDetails
实例,但大多数属性都保留了nil值。 那没关系,但稍后您尝试在同一个实例上查找exerciseName
,setsNumber
和repsNumber
。由于您的实例都没有全部三个值,因此您的应用程序崩溃了。
这种情况正在发生,因为Core Data知道可选值是什么,Swift也知道“可选”是什么意思,但这些不是同一个东西。 Core Data并不关心你是否将这些属性保留为nil值,但Swift确实如此。这两个想法之间的冲突导致了你的问题。
你应该做什么:
TrainingDetails
类以使其成为Swift选项。看起来你正在使用Xcode生成的代码,但是代码错误并且完全可以修复它。然后,编译器将强制您检查属性是否具有值,并且不会崩溃。TrainingDetails
必须包含每个属性的值,那么您应该做两件事。首先,编辑您的核心数据模型。对于其中的每个属性,请取消选中模型编辑器中的“可选”框。这样,Core Data就会知道不允许使用nil,如果你有意外的nils,它将阻止你保存更改。其次,您需要将上述三种方法更改为(a)始终为所有属性赋值,或者(b)重复使用相同的TrainingDetails
实例,而不是在每种方法中创建新实例(选择取决于您的要求,因此由您决定哪个是正确的。答案 1 :(得分:0)
在你的函数appendNumberOfReps()
中,似乎你使用点语法将它添加到TrainingDay
对象(不确定你定义它的位置,虽然我假设它是一个NSManagedObject?)。在您的核心数据实体TrainingDay
中,创建一个名为repsNumber
的属性,我假设我们可以将其设置为String
并尝试此操作:
// Save To Core Data
let entityDescription = NSEntityDescription.entityForName("TrainingDay", inManagedObjectContext: moc!)
let trainingday = NSManagedObject(entity: entityDescription!, insertIntoManagedObjectContext: moc)
var error: NSError?
moc?.save(&error)
trainingday.setValue(repsNumber.text!, forKey: "repsNumber")
if !moc.save(&error) {
println("Could not save \(error)")
} else {
println("Exercise: #\(repsNumber.text) saved successfully!")
}
然后,为了正确设置表,最简单的方法是通过读取数组的计数和数据进行设置。所以也许您可以调用Core Data来返回数据,然后将它们附加到名为var repsArray: String = []
的数组中:
// Fetch From Core Data
let trainingFetchRequest = NSFetchRequest(entityName:"TrainingDay")
let fetchedResults = moc.executeFetchRequest(trainingFetchRequest, error: &error) as? [NSManagedObject]
if let results = fetchedResults {
if results.count > 0 {
for index in 0...results.count-1 {
let match = results[index] as NSManagedObject
repsArray.append(match.valueForKey("repsNumber") as! String)
}
}
}
然后通过使用repsArray
(仅举例来说)返回行数来计算表中应该有多少行可能更容易:
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
return repsArray.count
}
然后只要您拥有正确的表格单元格类(例如,下面的CustomCell
)和在Interface Builder中创建的标签名称(例如,下面的repNumberLabel
),然后附加到{{ 1}},你可以使用indexPath.Row来处理你构建的数组:
CustomCell
希望这对您已经尝试的内容有所帮助并且不会多余!在尝试保存到Core Data然后检索数据以便在表格单元格中使用时,这对我有用。