How do I use a UIViewController as a dialog? - iphone

I have a UIViewController that I want to display a second UIViewController as a dialog. Basically, the user presses a button in the first controller, then the second controller pops up and the user makes a selection.
When the user presses Save in the second controller, how does control get passed back to the parent controller, and how can I extract the user's choice from the second controller?

Consider looking into setting up a Modal View Controller under your root controller.
You could set up a property that stores the choice or selection. Its value would be accessible to the root controller through its instance of the modal view controller.

It seems like there are two leading ways to do this:
Create a custom delegate. Make the parent controller the delegate of the child controller. Have the child controller call an appropriate method in its delegate and simply use popNavigationController when you're done.
Create a member variable in the parent controller referring to the child controller. When you display the child controller, store it in the member variable. Then override viewWillAppear: in the parent controller so that if the child controller reference is non-nil, it will interrogate the child for whatever information it needs. Then set the reference back to nil.
I personally like the second better. YMMV.

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.

iOS: Call method in tabs viewController

I'm trying to come up with something simple, but i can't figure it out.
I have a UITabBarController and at one point I have to display another tab's UIViewController, and call a method in that new UIViewController, using data from the original UIViewController.
So basically I want to pass data to another UIViewController (that may not be initialized yet), and show the right tab.
If I use NSNotificationCenter, I'm not sure if the tab's UIViewController is initialized yet, and also it's a bit ugly to use delegation here.
What is a clean way to send and show data in the new tab?
A better idea would be to have a protocol implemented in the tab view controller the view controller can call to send data and set up any other view controller
You should have a data model of some sort (singleton?) that is accessible by both view controllers. When the second view controller is about to display its view, it should reference the data model to determine the data it should display.
int x = 1; //this is the view controller you want to go to.
MySecondViewController *secondViewController = (MySecondViewController *)self.tabBarController.viewControllers[x];
[secondViewController setDataObject:dataObject];
[self.tabBarController setSelectedIndex:x];
So what's happening is you're calling the controller from the tabBarController, it will initiate there if its not. Then you can set whatever you want on the controller, then you just switch to the selected tab.

using dismissModalViewControllerAnimated without deallocating modal view controller

I'm creating an app using the iPhone Utility App framework, and I'm trying to use a navigation controller on the flipside view, as there will be a lot of drilldown options on this view. When I'm done with this view, I call the following code:
- (IBAction)done:(id)sender
{
[self dismissModalViewControllerAnimated:YES];
}
When I dismiss this view, I want to be able to go back to the place in the navigation I was currently at when I reopen this view again. However, when I dismiss this view using this method, the vc gets deallocated, therefore the menu starts back at the beginning when I try to go back to the menu.
Thoughts?
You'll need to retain a reference to the object (I'm calling it the options controller). I would say the easiest way is to create an iVar in the presenting view controller that references the options controller. Then, when you go to present the options controller again, just present the referenced options controller rather than creating a new controller. If different view controller objects can present the options controller, you'll need to either pass that reference around, or store it in some object that all the other view controllers have access to.
Hmm not much code so maybe I'm misunderstanding your setup, but...
You could use the AppDelegate to store (as a property) your current position (index) in the views collection of the Navigation controller, and then write a method that pushes to that (stored) position when you re-visit it later.
Might be an easier way to do it though..
So what you want is to flip from a view to another view? If you want to keep the navigation bar status between flipping, I recommend you use only one view controller to control this 2 views. you can use + transitionFromView:toView:duration:options:completion: of UIView to flip views.

Best Way To Create an "Add" View Controller

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.

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.)