Best Way To Create an "Add" View Controller - iphone

I have a table view that contains a list of Project objects. When an item is selected it brings up a detail view. Pretty standard. What is the best way to implement "add" functionality (popup a modal view controller to input new values and save the item)?
Currently I have view controllers for my root view, detail view, and add view. Essentially the detail view and add view are exactly the same except for a save & cancel button in the add view. Is it possible to reuse the detail view in the add view?
Finally, what is the best way to display the list of project properties in a grouped table view separated into sections?
Thank you for your responses.

Most likely, you are already passing your detail view controller a managed object that it is supposed to display when in detail view mode. When the user decides to add a new project, just create a blank object, pass it to the detail controller and display it. (You might want to insert this blank object into another "empty" managed object context in case the user cancels the add process to avoid having to clean up your main managed object context in that case.)
The detail view controller would also need a flag that tells it whether it is in edit or add mode so it can adjust its controls (and possibly delegate messages it sends to its owner) accordingly. You would set the flag to the appropriate value before you display the controller.

It sounds like you're looking for a UINavigationController. The UINavigationController lets you push new view controllers on top of existing ones. It gives you a navigation bar at the top that will allow the user to go back to the root controller. I think it's the kind of controller Apple uses it in the default email application, to give you an example.
Concerning organization: you design your root view controller and a detail/add view controller. In your app delegate, you attach a UINavigationController to the window and you set its root controller to the main controller you want to display. That root controller can then push the add/detail controller onto the stack (and when it does so, it can tell the add/detail controller which types of button to display.)
I can't answer your grouped properties question, but it sounds like a separate question anyway.

Related

Global behaviour for event in root model class

I want to know what is best practice when triggering an event from a base model class, which will have a common outcome on all View Controllers. Say I have a shared, global variable, which can trigger an event based on different inputs. Wherever I am in my app, I wish to show a popup with the same information. With my knowledge of view controllers and swift, my only option is to implement the same code in each view controller, as I have to add that same popup to each view, depending on where I am.
Wouldn't it be nice if I could pop that popup from a global-root'ish view controller?
Is there a general coding-practice I've missed?
My first idea is to use a navigation controller (UINavigationController) as the root controller, and then just use
navigationController?.topViewController
from any view controller added to that navigation controller.
There might appear a problem: in case if you already displayed the alert view controller, the app will try to present an alert controller on top of another one. You can keep some kind of global state, or check the type of topViewController.

How to create a segue performing a transition to the same view with another model object?

I am writing an iOS / CocoaTouch app and I am facing the following problem :
I have a detail view (think of an overview of one given object)
This detail view can present other elements
Any of these other elements can be viewed in this exact same detail view (I mean, another instance of this view / view controller using the viewed object model.
The only problem I have is that I am not able to create a segue from a view to the same view in the storyboard editor. Therefore, I cannot create the segue at all, cannot assign an identifier, and thus cannot trigger it from code.
Is there any way to implement this ?
This is as simple as a detail view pushing another, each of them having one dedicated instance of the view controller with their respective object model.
Thank you so much, I looked everywhere and cannot find any topic related to this.
Christophe.
Segues are between view controllers, not views (even though a view can act as a trigger). If you want to have a segue to a new view controller, create a new instance of it in the storyboard, assign its identity to the same class as your original detail, and define the segue.
If you're only trying to change which view is displayed inside a single view controller, then selectively setting views hidden and not-hidden can work...or adding/removing sub-views.

iPhone: View / Edit / List controller

I have a customer view controller that is a subclass of UITableViewController. It has a list that lists all the customers. I have a + button in the top right. I want to make it so when people click the + it will go to the add customer screen and after you click save it will act JUST like the iphone contacts list and then display the newly added customer.
Would I need to create a controller for each view? One to display the list, one to add the person and one to view the contact then another to edit the contact? Or should I use one controller and just add a bunch of views in IB into the single view controller?
Create a CustomerListController for seeing ALL customers.
Create a CustomerViewController for viewing and editing the detail.
Subclass the CustomerViewController calling it CustomerAddController for creating, as this will need a little more functionality.
Core Data Recipes application will give you some good pointers around this.
If you want it to only create the record after you hit save, you'll need to:
Create an additional NSManagedObjectContext, assuming you're using Core Data.
Pass that context to the instance of the CustomerAddController class only (not needed for the view class).
When the Save button is hit, you'll need to merge the two NSManagedObjectContext classes in the CustomerListController.
I believe the way the Contacts app does it is:
Contacts list is a UITableViewController in a UINavigationController
Touching the + modally presents (from the navigation controller) a different view controller for adding the contact
Touching Done pushes a new view controller onto the navigation controller for viewing the newly created contact, but it isn't visible yet because the modally presented contact adding view controller is on top. Immediately afterwards, the modal view controller is dismissed, revealing the newly created contact.
To answer your question, I'd suggest using three different view controllers, just like the Contacts app.
I suggest you to use different views for every task because using one IB file uses more memory where as if you use different IBs and view controllers for every task then there is not too much memory is used and after completing one task for example when you save the user detail free the memory for that view so that you app do not use much memory.

iPhone: How to make UINavigationcontrollers inside eachother?

I have a navigation controller which I push a new tableviewcontroller for each received question to be asked to the user, so in stack it builds up to 30 controllers if there has been 30 question is asked.
The difficulty is that in some of the tableviewcontrollers I want to get the input from user by using another navigation controller inside that tableview: for example in the tableview(which is one the many views in the stack) there may be uitablecell with an arrow on the right saying choose the books you want to order, and when he clicks arrow a new tableview will slide in which includes the books to be choosen multiply with a checkmark, and then he will choose and back to main tableview and continue the main navigation there.
How can implement a new navcontroller inside the main navigation controller? or any better ideas?
EDIT: That can be an idea to push the detail view to the same controller, but then they will get popped immdidatly when user "backs" but I want to show the books (which are chosen in detail view) the main table, and when user clicks again to that cell, detailview will come with previous selected books. is this a good approach
Putting an UINavigationController inside a UINavigationController is a bad idea. What you seem to really want is persistence of state data after popping some of the view controllers off your navigation controller's stack.
I would put that state information into a persistent object. If it's a tiny amount of state data I may add that data to an existing object that I know is persistent, such as the app delegate or the root view controller. I would save a more complicated set of persistent data to a custom object. This object would be retained by the root view controller, and a reference would be given to each successive view controller. This object would have the data that may have been collected by a controller that was popped off the navigation stack and therefore no longer exists.
I don't really get why you dont just push the detailview of the uitableviewcontrollers to the main UINavigationController..
Could you explain that a little bit more detailed?
I have no rights to comment your question, so I am afraid I have to post this as an answer.
MfG,
SideSwipe

Managed Object Context in Tab Bar View

Ok. this one's a challenge.
I have a tableview within a navigation controller.
I push it from the root, where I have an add action that allows me to add a new record. That works fine.
Now what I've tried to do is add this tableview to a tab bar view (without a tab bar controller cuz that won't work) but within the same navigation controller.
So what I want to do is this: Root > TabBarView (loads Tableview) > add new record.
The problem lies in the managed object context, I get the whole "can't find entity error" but I have no idea how to fix it.
I've managed to get the AddRecord modal view controller to show up from the tabBarView, but it presents itself without a navigationbar, whereas if I try to add a record in the solitary tableView (outside of the tabbar) its no problem.
I'm now calling my methods from the TabBarView's navigationBarbuttons, routing through to the tableviews methods.
I know my methods have to be called from the tabBarView instead of the actual tableview now, and they do fire, but I don't know how to manage the MOC when its in a tabView.
Oh, and this is based on coredata recipes and books, so when the add record method is fired, it creates a new MOC to create it, then reintegrates back in the main MOC when you're done.
Any ideas?
It sounds like you have a couple of problems.
"Can't find entity" error -- this depends on which Managed Object Context you're using. If you created a separate MOC to manage the object you're editing (which is a good idea, by the way), make sure you assign it a Persistent Store Coordinator. This is how an MOC discovers what objects are available. If you're using the MOC created in the App Delegate, make sure you're spelling the name of the entity correctly.
No Navigation Bar in sheet -- When you push a view controller onto a navigation controller, its navigationItem is used to populate the navigation bar. When you present a view controller as a sheet, only the view controller is displayed. It is not embedded in a navigation controller. In order to get the navigation item to display, you'll need to create a new navigation controller with your view controller as the root, and then present the navigation controller's view.
As far as the main MOC goes, views and controllers should be irrelevant. Obtain a reference to the MOC in whatever controller you are using and operate with that MOC. If your application delegate creates the main MOC, make it a property of that delegate and access that from your view or tab controller.
I don't quite follow what navigation problem you're having, but if there's no navigation bar when you need one, I suspect you need to create and add a UINavigationController somewhere that you're adding a UIViewController subclass. Make the subclass the root of the new UINavigationController and put the controller into the tab or whatever.
Your managed object context (MOC) should not be dependent on navigation or views. It's part of the model. (Although as you know, a 2nd MOC for a cancelable edit view would be dependent on navigation to the extent that you create it for use by the editor.)