I'm just starting out with Core Data and I have an iPhone Core Data project set up in a master-detail view system. The master view contains items, and the detail view lets you edit the properties of the selected item.
I'm looking for the best options in order to implement the editing. Would I pass along the NSManagedObjectContext to the detail view controller to make modifications and save changes, or would that even work? Is there any example code that demonstrates how to do this?
I've done that before, pass the NSManagedObjectContext when pushing the detail view. I've also passed the object to the detail view and had the master view in control of saving, but that was for some quirk of workflow for that app.
Apple has some great sample code, like iPhoneCoreDataRecipes.
Related
In the top of my detailcontroller I have a button to show a list of selected items from various options on the detail controller.
I want to initialize and keep the model, the popover and the list objects in the mastercontroller. How can I get a reference to my mastercontroller to reuse these objects?
Sharing data between views is easiest using a model tied to the component. If you make sure that everything that's selected in the master model is contained in that model, you will be able to use the data from the model in the detail view again.
Pulling data directly from another controller would go against the MVC paradigm and is not recommended (although not impossible, using e.g. the sap.ui.getCore().byId() method). I would not go there unless you have a clear view of the consequences.
Still completely new to this whole xcode thing so bear with me..
Im using xcode 4's 'master-detail' template with core data. When you click a cell in the table of the rootView, it segues to a detail view passing selectedItem as managedobject "detailItem".
I want to add a "next" Button (or a swipegesture preferably, if possible) that will display the next cell/detailItem, from the table in rootView, in the detailView
(exactly like the notes.app)
Do i need to recreate a fetchedresults controller and pass the objectIndex then fetch index+1 And display that as next object?
Or is there an easier more efficient way that wont drive me crazy trying to fabricate???
any help would be Most appreciated. And hopefully detailed as i would barely understand it
I would create a delegate relationship between the master and detail view controllers. If you don't know how delegates work, check documentation in that link, and plenty of good tutorials are a Google search away… this one's not bad. Here's the high-level approach:
On the detail controller, you'll create an (id) delegate property, and a "DetailViewControllerDelegate" protocol with methods like -(BOOL)detailViewShouldShowNextItem:(DetailViewController *)detailViewController and a similar one for previous.
On the master controller, declare support for the protocol in the header, and then implement the delegate methods so that they select the previous or next item in the list, loading it in the detail view.
Finally, after the detail view controller is instantiated, set its delegate to be the master view controller.
Any advice on where to store the main list data for an iPhone application like the following?
NavigationController based
Level 1 (main screen) is a List of Items. Hence it uses a table view (table of items)
Level 2_EDIT: Is a view you can get to from the main screen by clicking EDIT. Here you can add text to be added to the main view list
Level 2_DETAIL: Is a view you can get to from the main screen by clicking on a cell.
Now assuming the implementation is (rough overview):
* MainView - appDelegate (holds UIWindow & UINavigationController)
* RootViewController - table view of the main items list (? variables here ?)
* EditViewController - input text to add to main list
* DetailViewController - shows detail of record
Question - Where to hold the NSArray that keeps the main list of items? Should it be in the RootViewController where the Table View exists that displays it? Or should it be higher up in the ApplicationDelegate? I note that when you go from RootViewController to EditViewController, then in this edit view you would have to ADD items to the array, so would it be easier for the code in the EditViewController to access the main array from the AppDelegate (as opposed to the RootViewController)?
(Note - still haven't made an app that has a specific model object, re MVC, yet, so not sure if this should come into the picture.)
Your data becomes the table view's data source, and although it doesn't have to, the view controller that contains the table view often does the data source's role. The view controller can also be a delegate for the EditViewController, so the EditViewController sends a message to it so it can update the array.
Apple's CoreDataBooks sample project show similar architecture. You may want to take a look.
Having the array in the application delegate is often not a great idea. Although it can give you a little bit of convenience, now your classes totally depend on your application delegate unnecessarily.
Your table view shows your data. This corresponds to View in the MVC design pattern. I assume RootViewController is the view controller of the table view, which acts as a Controller in the pattern. Your data, the location of which is not decided yet, corresponds to Model. The role of RootViewController becomes connecting the Model and View.
The ideal, or the reason of the MVC pattern is to isolate the model and the view, so the model can work with other views with appropriate controllers, and the view can also work with other models with appropriate controllers. For example, your RootViewController will provide the table view with data. It will specify the data in the language of table view, e.g. the number of sections and rows, the contents of cells, etc. If you want to present the data in a different way, for example a graph, your controller will access the same data (model) and provide the graph view with a different representation of the same data. The model need not change, neither do the views. You write only the controller, for each combination of a model and a view.
Ideally, therefore, you will have a different class for the model. In this class, you will store the array, and provide a general interface for controllers can interact with the data.
However, it's often not that necessary, either because it's unlikely that you will use the model class often again, or because the model itself is way too simple so it can be easily implemented anywhere. For example, if your data for the table is a simple array, an NSArray object is often sufficient for the model's role. Therefor, here comes an idea that to combine the controller and the model into a single object.
This is why it makes sense that your table view controller often acts as the data source of the table view.
However, storing the data in the application delegate is a completely different idea. Now the application delegate becomes your model, but which does not make sense, because the application delegate is only used for the specific application. Why would you have a separate model object that totally depends on a single application? Also, if your table view directly interacts with the application delegate, it means that now your view cannot work for other applications either because it now depends on the specific application's application delegate.
Often the reason why people are tempted to have data in the application delegate is, that the application delegate is easily accessible by any objects in the application by using [UIApplication sharedApplication].delegate. The M-V-C relationship is not always very simple. For example, your EditViewController also need to access the same model. To do this, you have to write some code to make the model accessible by both the table view and the edit view. If you have the data in the application delegate, you don't need to do anything, because you can magically access the array by accessing the application delegate.
But that's all. A few minute's saving in your coding time, for the price of ruining your software architecture. I'm not a fundamentalist, and I do sometimes use application delegate to store some data when I'm absolutely sure that it's not worth to provide well-formed interfaces, but it's rare.
So how should you connect your edit view to the data merged into the table view controller? There could be multiple ways. What I suggested before is let the edit view controller has a weak reference to the table view controller (delegate) and send a defined message, for example - (void)editViewController:(EditViewController *editViewController) didFinishEditing:(id) someData. In this way, you can use this edit view controller with some other view controllers as long as they use the same protocol. But others may implement different interfaces for it.
You need to store in the appDelegate,as you can acees the data in anyviewcontroller then.But if you use rootviewController,then you can only send data to next ViewController then,not to the 2nd or 3rd ViewController directly.
Hope it will help you.
Good Luck
I have a program that displays a list (a TableView).
When the user clicks an item, it's detail is shown.
On the detail view, the user can ask to modify it so a modify window is shown.
Here, the user can ask to delete the item.
I would like at this time return to the list with the item deleted from the list and from the data source.
There may be thousands of methods to do this, but I wonder which is the best / good one.
Could you help me, and/or give me a good reference to read about this ?
I think he ask how to get from view number 3 back to first view.
Then you can put your three views inside a UINavigationController and call on the last view popToRootViewControllerAnimated:
at least Two options:
Delegation - Create a protocol called something like: TableDetailModifierDelegat
and add methods like modifierDidChangedItem:(id)item
or modifierDidDeleteItem:(id)item
and to the modifying view controller add instance variable id so when you done editing or deleting you will call the appropriate methods.
of course you will need to make your table view controller implement the protocol you created. if you modified or deleted an item you should update your data source and reload the data to the table.
also pass the Table View Controller as the delegate when creating the Modifying View Controller.
Passing The Data Model.
This is much more simple to implement.
you can simply pass your data model to the modifying view controller, and make the changes directly to the data model.
You should keep the data model as Instance Variable in the modifying view controller.
when you done, dont forget to reload the data to your table.
In this instance, you could simply remove the data from the data source the UITableView is using and then call the reloadData method on the table. (As you're editing the data in question, you'll presumably have a suitable method/reference by which to delete it.)
As a bit of reading, I'd recommend Apple's Table View Programming Guide for iOS - this provides a lot of useful background information.
I'm diving into iOS development and am getting familiar with navigation view controllers. I'm trying to build a simple app with a table view that allows me to add objects to it. So far, I have a table view with an add "+" button in the nav bar that allows me to load my CreateObjectView and display it modally so the user can define the new object, but when they click the save button, I don't know how to send that object data back to the parent view that created the CreateObjectView that contains the object data.
When I create the child view (CreateObjectView), I could pass into it a pointer to the current view before I push it onto the nav stack, but this just feels dirty and circular.
I was reading about protocols and delegates and I could use that approach as well, but it also feels circular.
This question seems like it would be a common design issue to any tableview-based or nav-based app, how should I probably access the view that is one level up from my current view in a nav-based iOS app?
Thanks so much in advance for all your help!
It feels circular at first, but it is the right way. Before the UINavigationController pushes the new view controller you should set the delegate to the current view controller - assuming that's the object you wish to communicate with. Of course you could set it somewhere else instead, such as to a central Core Data handler. Then when you need to communicate call the delegate with the method you have defined. I've done several navigation apps like this after seeing Apple's cookbook example, and it really works well.