Below is what I want to implement:
The main screen of my app is a UITableView. Each row in the table view is a category, when you click the detail disclosure button in the row, you can see a bunch of items under this category in the category detail view.
Now in the main screen, I click the "+" button in navigation bar to create a new category. (The new category will become a new row in the table view). The app then take me to the "Add Category" view. (I used presentModalViewController)
In the "Add Category" view, I set something, then click "Save" button to dismiss the "Add Category" view. (I used dismissModalViewControllerAnimated)
Usually after I click "Save" button, the app will take me back to the main view and I will see a new row in the table.
But that's not what I want to go, what I want is - after I click the "save" button, the "Add category" view will be dismissed but not return to the main view. Instead, I will see the details of the new-created category so I can continue to add items under this category. The result is just like "I return to the main view and then click the detail disclosure button of the new-created row (category)".
Does any one know how to realize that? Thanks!
You can do this by doing a little decoupling of one screen from another:
- Create a custom delegate and protocol for your category creation modal dialog. Something simple like:
#protocol CategoryCreationProtocol
- (void) categoryAddDone:(NSString *)category;
- (void) categoryAddCancelled;
#end
...
#interface CategoryCreationDialog : UIViewController {
...
id<NSObject, CategoryCreationProtocol> categoryDelegate;
}
#property (assign) id< CategoryCreationProtocol, NSObject> categoryDelegate;
- In the modal dialog when the user taps the 'Save' button, after dismissing the view controller, you invoke the delegate method:
if (categoryDelegate && [categoryDelegate
respondsToSelector:#selector(categoryAddDone:)])
[categoryDelegate categoryAddDone:newCategory];
Also, something similar for the Cancel button.
- Your main controller implements the categoryAddDone method and sets itself to be the categoryDelegate for the modal dialog.
- At runtime, when the user taps Save the delegate method is invoked so your main view is notified that something has happened and it can push the right view into place and even jump to the proper category.
- In your case, as soon as the category creation is done, the main view controller is notified, so it can release the category creation dialog and push the category detail view into the stack. The user sees the modal dialog disappear and slides right into the detail view.
- In general, using delegate/protocols for push navcontroller and modal dialogs is a really handy pattern for making decoupled and reusable views. This way they can be invoked from a variety of places. To make it consistent, you may also want to have a show method on each modal dialogs and pushed view controllers that the caller can invoke. This way there's a consistent way to get into and a consistent way to get notified that the user is done with it.
If you use presentModalViewController and its corresponding dismissModalViewControllerAnimated, then you will return to the view controller in which you issued the initial presentModalViewController message.
Instead, you may want to push on the stack the view controller in charge of adding the new category, and when you are done, you simply push on the stack the view controller responsible for showing all of the items of that category. Thus, you should use
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
Related
I'm trying to execute code when a button is pressed for an application but I can't find how to change the views after the code is executed. Is there a way to switch views how I want to or is there another way? Thank you in advanced, I'm very new to xcode.
edit: I'm trying to go from one view to another, not the view controller and yes I have one storyboard that I planned on using for the whole project if possible.
To execute code when a button is pressed, you have to set up a method that the button is hooked into. Because you said you're using storyboards, I'll assume your button is on the storyboard. Go to the assistant editor, hold ctrl, and click-and-drag from the button to the view controller's .m file (#implementation section). This will create an IBAction method, and any code in this method will execute whenever you press the button.
The method will look like this:
- (IBAction)aButtonPress:(id)sender {
}
According to your comments, you say you only want to change the on-screen view, and not transition from one view to the next.
Views are added and removed with the following methods:
[aSuperview addSubview:aSubview];
[aSubview removeFromSuperview];
I can't really tell you much else with a lot more detail from you... and even though I asked twice in the comments and you said you only want to change the view, not the view controller... I think you probably need to transition to a new view controller. Impossible to know for sure as you've given almost no detail...
But if you want to transition between view controllers (which also transitions views), then ...
Create two view controllers on the storyboard. Hook them together with a segue, and give that segue a name. Now, to perform that segue in code:
[self performSegueWithIdentifier:#"YOUR_SEGUE_NAME" sender:self];
I am showing a ExchangeWardrobe view.In this view i have a button Mywardrobe on click on this button,opens User’s own Exchange Wardrobe.This will have following 3 tabs..one is myProducts view..in which there is one button offer..click on this offer button open Product detail page..which is also in another tabbarcontroller..so I want to ask Is it possible that a class of one tabbarcontroller can call another class of another tabbarcontroller?
In your app delegate you can add and remove tab bar controllers from your main window (ie [window addSubview:usersWardrobeTabBarController.view]).
just create a method in your app delegate that swaps these views adds/removes them from your window. Or if memory isn't an issue then add them both and hide/unhide them.
I have a view that creates a new core data managed object, and fills in all the required properties and also allows optional ones. I originally had a "Done" button on the top left, and when that was pressed, I validated the object then saved and removed the view.
Now I have an edit/done type setup on the top right, so sometimes there are two identical "Done" buttons on the top of the view. I want to switch the left side button so that it just has the normal "Back" button, then somehow validate and stop the view from being removed if it doesn't validate. I can't find any way to capture the method called by that back button and modify it, and viewWillDisappear doesn't work cause there's no way to abort the disappearing.
How can I make this work? I need to validate this, then save, then remove the view if validate and save worked only.
It sounds like your view is a perfect candidate to be pushed modally instead of through the navigation controller stack.
Push the view that creates your NSManagedObject modally:
[self presentModalViewController:yourViewController animated:YES]
Then continue to use your top right EDIT/DONE button for editing/validation as you currently are and when validation is successful simply save your object and dismiss the modal view controller from the parent view controller:
[[self parentViewController] dismissModalViewControllerAnimated:YES];
For more details check http://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/ModalViewControllers/ModalViewControllers.html#//apple_ref/doc/uid/TP40007457-CH111-SW14
If you still want to use a button on the left hand side perhaps you can change the right button to say EDIT/CANCEL and add a DONE button on the left side that is only visible when you're not in EDIT mode. If appropriate you can point the DONE button to run through the same validation process before dismissing the modal view using the code above but it probably makes sense that the EDIT/CANCEL button takes care of it.
I hope this helps.
Rog
There is no documented way to intercept the standard back button of UINavigationController. If you want this functionality, your only option would be to customize leftBarButtonItem with a custom button.
When the user taps that button, you can first validate your object and then call popViewControllerAnimated:.
It's hard to mimic the look of the built-in back button, though.
I am developing an application in which I am using a login form at first screen. If the user is new he is takne to the signup form and after that he is also taken to the home page as a normal user.
Now my question is "If the new user presses back btn, how can I direct him back to the login page and not to the sign-up forms and all in between?"
Should I change the navigationcontroller's viewControllers array?
- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated on UINavigationController will pop the user back to the last view controller in the stack.
If you want to get the navigation stack to a new known state you can use - (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated the last item in the array will then be the active one.
UIViewController has some methods for this. You can use
- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated
to pop up to the top view controller, or
- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated
to keep popping until you get to a specific controller you know is on the stack somewhere...
Perhaps you should think about your problem from another angle.
The signup form isn't really part of the flow of things--it's a temporary, one-time, mandatory interjection.
If you made the signup form a modal view, then you could just dismiss the modal view when signup is complete (or cancelled) and move normally to the next view controller.
That way, when you back up, the login view is the immediately previous one.
I have a very simple scenario:
My iPhone application contains a UIViewController implementation which displays a list of items. In its navigation bar there is a button for adding items to that list. When this button is clicked, a new UIViewController is instantiated and presented on the screen using:
[self presentModalViewController:controller animated:YES];
This controller contains views that take user input for a new item in the list. After the user is done entering information, he clicks the "Done" button.
The "Done" button should take all entered information and return it to the first controller (the one displaying the list). The first controller could then add an item to its list based on the information that was just entered.
My question is: How do I send back the information from the second controller to the first controller in a nice fashion?
You can use protocols...In your modal view controller you can define a protocol that must be implemented by its delegate say the method -(void)userDidEnterInfo:(some sort of info), in your view controller that you want to pass the info to you can conform to the protocol and become the view controllers delegate...right before you dismiss or whenever you are r eady to send the info over you can call [delegate userDidEnterInfo:] and the view controller will receive the information...Heres more on protocols http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15