用答案更新
import UIKit
import CoreData
class ExerciseViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UIPickerViewDataSource, UIPickerViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
VDL()
//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 daysPickerView: UIPickerView!
@IBOutlet var exerciseName: UITextField!
@IBOutlet var setsStepper: UIStepper!
@IBOutlet var repsStepper: UIStepper!
@IBOutlet var setsNumber: UILabel!
@IBOutlet var repsNumber: UILabel!
var namesArray = [String]()
var setsArray = [Int]()
var repsArray = [Int]()
var daysArray = [TrainingDay]()
var detailsArray = [TrainingDetails]()
func VDL () {
let fetchRequest = NSFetchRequest(entityName: "TrainingDay")
let sort = NSSortDescriptor(key: "dayIndex", ascending: true)
fetchRequest.sortDescriptors = [sort]
daysArray = (moc!.executeFetchRequest(fetchRequest, error: nil) as? [TrainingDay])!
if daysArray.count == 0 { // nothing there
let dayEntity = NSEntityDescription.entityForName("TrainingDay", inManagedObjectContext: moc!)
let days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
for (index, name) in enumerate(days) {
let newDay = TrainingDay(entity: dayEntity!, insertIntoManagedObjectContext: moc)
newDay.day = name
newDay.dayIndex = index
daysArray.append(newDay)
}
var error: NSError?
moc!.save(&error)
}
}
func appendTrainingDetailsToArray () {
let nameLabel = exerciseName.text
namesArray.append(nameLabel)
let numberOfSets = setsNumber.text?.toInt()
setsArray.append(numberOfSets!)
let numberOfReps = repsNumber.text?.toInt()
repsArray.append(numberOfReps!)
let row = daysPickerView.selectedRowInComponent(0)
let currentDay = daysArray[row]
let detailsEntity = NSEntityDescription.entityForName("TrainingDetails", inManagedObjectContext: moc!)
let trainingdetails = TrainingDetails(entity: detailsEntity!, insertIntoManagedObjectContext: moc)
trainingdetails.trainingDay = currentDay
var error: NSError?
moc?.save(&error)
if let err = error {
var status = err.localizedFailureReason
println("\(status)")
} else {
println("CURRENT SETTING: \(trainingdetails.trainingDay)")
}
}
@IBAction func doneButton(sender: AnyObject) {
appendTrainingDetailsToArray()
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
println("\(row)")
let details = detailsArray[indexPath.row]
cell!.textLabel!.text = details.exerciseName
cell?.detailTextLabel?.text = "Sets: #\(details.setsNumber) Reps: #\(details.repsNumber)"
return cell!
}
//PICKER VIEW DELEGATE AND DATASOURCE METHODS
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return daysArray.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
let trainingDay = daysArray[row]
return trainingDay.day
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let currentDay = daysArray[row]
let fetchRequest = NSFetchRequest(entityName: "TrainingDetails")
let predicate = NSPredicate(format: "trainingDay = %@", currentDay)
fetchRequest.predicate = predicate
let sort = NSSortDescriptor(key: "exerciseName", ascending: true)
fetchRequest.sortDescriptors = [sort]
detailsArray = (moc!.executeFetchRequest(fetchRequest, error: nil) as? [TrainingDetails])!
exerciseTableView.reloadData()
}
}
以前,我曾寻求帮助,因此可以适应UIPickerView。
就像@pbasdf所说的那样,代码需要进行一些调整以符合核心数据和选择器视图。您可以在他的回答中看到他的解释!
最佳答案
有几件事要解决:
TrainingDay实体
您对awakeFromInsert
代码的选择是错误的。它不会插入新对象;只要您插入新的TrainingDay
对象,它就会运行。从我在您的代码中看到的,您实际上从未插入新的TrainingDays(这很幸运,因为awakeFromInsert将崩溃-您正在将字符串数组分配给作为字符串的属性)。
您需要创建7个TrainingDay对象,一周中的每一天一个。由于这些不会更改,因此您可以在首次运行应用程序时将其作为一项一次性任务来完成,或者在尝试获取它们时(如下面所述)“懒惰”地完成。您不需要awakeFromInsert
代码,但是我建议向该实体添加另一个属性,例如“dayIndex”,这将使您能够将TrainingDay对象按逻辑顺序排序。您的代码可能看起来像这样:
// load the TrainingDays data...
let fetchRequest = NSFetchRequest(entityName: "TrainingDay")
let sort = NSSortDescriptor(key: "dayIndex", ascending: true)
fetchRequest.sortDescriptors = [sort]
daysArray = (moc!.executeFetchRequest(fetchRequest, error: nil) as? [TrainingDay])!
if daysArray.count == 0 { // nothing there
let dayEntity = NSEntityDescription.entityForName("TrainingDay", inManagedObjectContext: moc!)
let days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
for (index, name) in enumerate(days) {
let newDay = TrainingDay(entity: dayEntity!, insertIntoManagedObjectContext: moc)
newDay.day = name
newDay.dayIndex = index
daysArray.append(newDay)
}
moc.save(&error)
}
您可以将其放在
viewDidLoad
或VDL调用的函数中。然后,您可以将daysArray
用作选择器视图的数据源...填充选择器视图
放弃
daysOfPickerView
,改为使用daysArray
...//PICKER VIEW DELEGATE AND DATASOURCE METHODS
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return daysArray.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
let trainingDay = daysArray[row]
return trainingDay.day
}
将TrainingDetails对象分配给正确的日期
在
appendTrainingDetailsToArray
方法中,您需要确定在选择器视图中当前选择的日期。为此,您将需要为pickerView添加@IBOutlet var并将其连接到情节提要中。然后您可以访问它并设置TrainingDetails的关系...let row = pickerView.selectedRowInComponent(0)
let currentDay = daysArray[row]
trainingDetails.trainingDay = currentDay
填充表格视图
当前,您正在使用三个单独的阵列。我只会用一个:
var detailsArray = [TrainingDetails]()
然后使用
TrainingDetails
的属性来填充表格视图单元格,即。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 details = detailsArray[indexPath.row]
cell!.textLabel!.text = details.exerciseName
cell?.detailTextLabel?.text = "Sets: #\(details.setsNumber) Reps: #\(details.repsNumber)"
return cell!
}
修改其他表视图数据源方法,以同样使用detailsArray。
您的三个数组当前是使用
append...
方法构建的,但是我想您想要的是在选定的日期使用正确的'TrainingDetails'填充表格视图...响应于选择器视图更改
当前,每次选择器视图更改时,您的代码似乎都会创建新的
TrainingDetails
。相反,只需获取所选日期的TrainingDetails,然后重新加载表即可:func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let currentDay = daysArray[row]
let fetchRequest = NSFetchRequest(entityName: "TrainingDetails")
let predicate = NSPredicate(format: "trainingDay = %@", currentDay)
fetchRequest.predicate = predicate
let sort = NSSortDescriptor(key: "exerciseName", ascending: true)
fetchRequest.sortDescriptors = [sort]
detailsArray = (moc!.executeFetchRequest(fetchRequest, error: nil) as? [TrainingDetails])!
exerciseTableView.reloadData()
}
进一步的思考
您已经声明了
NSFetchedResultsController
,但没有使用它。使用它而不是原始的NSFetchRequest是有意义的,因为它将自动响应您添加新的TrainingDetails并将其添加到表中-而不需要使用reloadData()。但这是另一天...另外,如果您会原谅我,那么您可以选择一些自由项:!和?。我将它们保留在复制代码的位置不变,但是您可以整理它们。同样,对于上下文操作使用
error
参数-总是值得使用它。就是说,我起草以上代码时并未在Xcode中对其进行测试,因此,如果我在某些地方犯了一些错误,请原谅。希望你能看到这个主意。