我是Swift和编码的新手,仅仅一个月左右,我正在尝试构建一些简单的UItableViews来设置一些CoreData属性。
我的CoreData实体的结构是锻炼实体和锻炼实体之间的多对多关系。 (我会张贴一些图片,但我没有足够高的代表!)
我想要实现的是一个简单的设置菜单,用户可以通过在顶部使用带有navigationController的tableViews创建一个Workout,然后在该Workout中创建一系列练习(就像iOS设置菜单一样)
目前我已经开始工作了,你可以添加一些锻炼,然后你可以去Excercises tableView添加一些练习。但是我无法做两件事:
1)当用户添加练习时,如何将其分配给他们从上一个tableView中选择的正确锻炼,我该如何确保?
2)我怎样才能确保练习表只显示他们选择的锻炼练习?
我已经围绕这个主题做了很多阅读,并认为答案与从锻炼到练习的segue有关(通过使用委托将exerciseName传递给Exercises tableView?然后使用NSPredicate来限制选择锻炼显示的锻炼?
我不是百分百肯定,但是非常感谢任何帮助!
以下是从锻炼到锻炼的segue代码:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "excerciseMaster" {
let ExcerciseMasterTableViewController = segue.destinationViewController as UIViewController
let indexPath = tableView.indexPathForSelectedRow()!
let workout = workouts[indexPath.row]
let destinationTitle = workout.workoutName
ExcerciseMasterTableViewController.title = destinationTitle
}
}
这是我的Exercises tableViewController的代码:
import UIKit
import CoreData
class ExcerciseMasterTableViewController: UITableViewController {
// Create an empty array of Excercises
var excercises = [Excercises]()
// Retreive the managedObjectContext from AppDelegate
let managedObjectContext = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext
override func viewDidLoad() {
super.viewDidLoad()
// Use optional binding to confirm the managedObjectContext
if let moc = self.managedObjectContext {
}
fetchExcercises()
}
func fetchExcercises() {
let fetchRequest = NSFetchRequest(entityName: "Excercises")
// Create a sort descriptor object that sorts on the "excerciseName"
// property of the Core Data object
let sortDescriptor = NSSortDescriptor(key: "excerciseName", ascending: true)
// Set the list of sort descriptors in the fetch request,
// so it includes the sort descriptor
fetchRequest.sortDescriptors = [sortDescriptor]
if let fetchResults = managedObjectContext!.executeFetchRequest(fetchRequest, error: nil) as? [Excercises] {
excercises = fetchResults
}
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// How many rows are there in this section?
// There's only 1 section, and it has a number of rows
// equal to the number of excercises, so return the count
return excercises.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("Excercise Cell", forIndexPath: indexPath) as UITableViewCell
// Get the Excercises for this index
let excercise = excercises[indexPath.row]
// Set the title of the cell to be the title of the excercise
cell.textLabel!.text = excercise.excerciseName
cell.detailTextLabel!.text = "\(excercise.sets)x\(excercise.reps)"
cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
return cell
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if(editingStyle == .Delete ) {
// Find the Excercise object the user is trying to delete
let excerciseToDelete = excercises[indexPath.row]
// Delete it from the managedObjectContext
managedObjectContext?.deleteObject(excerciseToDelete)
// Refresh the table view to indicate that it's deleted
self.fetchExcercises()
// Tell the table view to animate out that row
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
save()
}
}
// MARK: UITableViewDelegate
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let excercise = excercises[indexPath.row]
}
let addExcerciseAlertViewTag = 0
let addExcerciseTextAlertViewTag = 1
@IBAction func addExcerciseButton(sender: AnyObject) {
var namePrompt = UIAlertController(title: "Add Excercise",
message: "Enter Name",
preferredStyle: .Alert)
var excerciseNameTextField: UITextField?
namePrompt.addTextFieldWithConfigurationHandler {
(textField) -> Void in
excerciseNameTextField = textField
textField.placeholder = "Title"
}
namePrompt.addAction(UIAlertAction(title: "Ok",
style: .Default,
handler: { (action) -> Void in
if let textField = excerciseNameTextField {
self.saveNewItem(textField.text, workoutName: "Workout A")
}
}))
self.presentViewController(namePrompt, animated: true, completion: nil)
}
func saveNewItem(excerciseName : String, workoutName: String) {
// Create the new excercise item
var newExcercise = Excercises.createExcerciseInManagedObjectContext(self.managedObjectContext!, name: excerciseName)
println(excerciseName)
println(workoutName)
// Update the array containing the table view row data
self.fetchExcercises()
// Animate in the new row
// Use Swift's find() function to figure out the index of the newExcercise
// after it's been added and sorted in our Excercises array
if let newExcerciseIndex = find(excercises, newExcercise) {
// Create an NSIndexPath from the newExcerciseIndex
let newExcerciseIndexPath = NSIndexPath(forRow: newExcerciseIndex, inSection: 0)
// Animate in the insertion of this row
tableView.insertRowsAtIndexPaths([ newExcerciseIndexPath ], withRowAnimation: .Automatic)
save()
}
}
func save() {
var error : NSError?
if(managedObjectContext!.save(&error) ) {
println(error?.localizedDescription)
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "excerciseSettings" {
let ExcerciseSettingsDetailViewController = segue.destinationViewController as UIViewController
let indexPath = tableView.indexPathForSelectedRow()!
let excercise = excercises[indexPath.row]
let destinationTitle = excercise.excerciseName
ExcerciseSettingsDetailViewController.title = destinationTitle
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
答案 0 :(得分:0)
1.塞古很接近。您的ExcerciseMasterTableViewController没有名为workout的属性。你需要添加
var workout:Workout!
到你的ExcerciseMasterTableViewController。
你的seque看起来应该更像这个
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "excerciseMaster" {
let desitnationController = segue.destinationViewController as ExcerciseMasterTableViewController
let indexPath = tableView.indexPathForSelectedRow()!
let workout = workouts[indexPath.row]
destinationController.workout = workout
let destinationTitle = workout.workoutName
desitnationController.title = destinationTitle // Usually you would put this in the viewDidLoad method of the destinationController
}
}
然后在你的ExcerciseMasterTableViewController中添加练习时,只需设置他们的训练属性
workout.exercises = exercises // See note in #2