【发布时间】:2015-02-21 21:13:12
【问题描述】:
我是 Swift 和编码的新手,才大约一个月,我正在尝试构建一些简单的 UItableViews 来设置一些 CoreData 属性。
我的 CoreData 实体的结构是锻炼实体和练习实体之间的多对多关系。 (我会发布一些图片,但我没有足够高的代表!)
我想要实现的是一个简单的设置菜单,用户可以在其中创建一个锻炼,然后使用顶部带有导航控制器的 tableViews 在该锻炼中创建一系列练习(就像 iOS 设置菜单一样)
目前我已经让它工作了,你可以添加一些锻炼,然后你可以去 Excercises tableView 添加一些锻炼。但是我无法做两件事:
1) 我如何确保当用户添加一个练习时,它被分配到他们从上一个 tableView 中选择的正确锻炼?
2) 如何确保锻炼表视图仅显示他们选择的锻炼锻炼?
我已经围绕该主题进行了大量阅读,并认为答案与从锻炼到练习的转接有关(通过使用委托将锻炼名称传递给练习表视图?然后使用 NSPredicate 来限制显示给所选锻炼的练习?
我不是 100% 确定,但我们将不胜感激任何帮助!
这是从锻炼到锻炼的代码:
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
}
}
这是我的练习 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.
}
}
【问题讨论】:
标签: ios uitableview swift core-data segue