Where should I "save" changes in my iPhone view to 'create new' of an object? - iphone

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.

Related

Trying to change views after button is pressed

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];

iPhone Storyboard, programmatically calling segues, navigation issues

So I have an iPhone app. It has a simple structure, all based on a UINavigationController.
I have a storyboard that has one view, a segue to another view, etc. Now this other view has a UITextView that I do not want to edit on this screen - if the user taps this, I want it instead to fly over to a second screen which basically has the same text view, but this one is full-screen, and the user will edit the text on that screen before returning to the previous screen.
So I capture the textViewShouldBeginEditing method. I previously, in the storyboard editor, manually created a push segue from the previous view controller to this new view controller, and named it so that I can call it by it's identity, which I do with:
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
// This is called when the user clicks into the textView as if to edit it.
// Instead of editing it, go to this other view here:
[self performSegueWithIdentifier:#"editMemoSegue" sender:self];
// Return NO, as I don't actually want to edit the text on this screen:
return NO;
}
Seems reasonable. And it works. Sorta. It does in fact shoot me over to that other view. That other view's events fire up, I set it's text view to become first responder, I edit the text on that screen. Everyone's happy.
Until I want to use the back button to return to the previous view.
Then I quickly find out - my navigation stack is foobared. Most of the time, I have, for some reason, TWO instances of my new editing controller on the stack, so the first time I hit the back button I get the same stuff over again. Then, oddly, occasionally, it will work as intended, and I will see my previous controller with only one back click.
I started reading the log, and I found this:
2012-12-09 09:41:03.463 APP[8368:c07] nested push animation can result in corrupted navigation bar
2012-12-09 09:41:03.818 APP[8368:c07] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
2012-12-09 09:41:03.819 APP[8368:c07] Unbalanced calls to begin/end appearance transitions for <SecondController: 0x83881d0>.
So obviously, I'm doing something incorrectly here. The question is, what? And how do I do what I want in the way that correctly appeases the tiki gods of the iPhone framework?
Check to see if the textViewShouldBeginEditing is being called twice. I've noticed that these kinds of delegate calls sometimes are.
How is your #"editMemoSegue" being created on the storyboard? is it created from the textView? if it is then you should recreate it directly from the view controller or from the top status bar on the view controller that way it wont be called twice when you touch the trigger object and when you call it programmatically.

Add a custom back button to Navigation Bar using MonoTouch

Just want to confirm this, as I'm trying to learn monoTouch alone..
I have a view which I navigate to using NavigationController.PushViewToController(). On the destination view, I have a Navigation Bar. I can add a button to the bar and use code to push to another view (I happen to know where Back is), fine.
Is there a existing "back button" control? Or a way in to code to change the existing back button to say "Go back"?
In Interface Builder I can see there is a property on the navigationItem called "Back". When I add text to this I can see a new BarButtonItem added to the navigationBar. However I never see this button when I navigate to the view in the simulator. If I try to drag the item onto the view manually, the "Back" text is cleared and the button is treated like a custom button.
Do I always have to manually code the back button?
The default back button (the one that takes the name of the previous controller) cannot be customized. But you can hide it and replace that button with a new one.
If you have a controller, you can do that on the viewDidLoad method. Overriding this method you are sure that all the elements have been set.
// allows you to hide the back button
NavigationItem.SetHidesBackButton(true,true);
// allows you to create a new customized button
NavigationItem.LeftBarButtonItem = new UIBarButtonItem(...);
UIBarButtonItem takes an handler that you can use to control the navigation.
In the handler you can do this:
NavigationController. PopViewControllerAnimated(true);

UINavigationController skipping a pop

I have 3 view controllers, one is the root, which pushes the next, which pushes the next. Each time you can go back (pop), using the normal back button that appears by default.
However when the 3rd view is visible, when the user taps the back button I need it to skip out the the 2nd view controller, and go (pop) directly to the root view controller.
How can I override the default back button behaviour? (I'd like to keep the shape of the back button, and not replace it with a square bar button)
You could try to have an object implement UINavigationControllerDelegate and enforce this behavior. You could also have a designer create the same size and shape asset and you could use this as the background for a button.
However, I'd rethink your UI if you really need to do this. It is contrary to the user's expectations of how a navigation controller should work.

Assigning a IBAction to the Back Button of the Navigation Bar (iPhone SDK)

In this (Flip View Iphone) post, I have created a flip view for my iPhone app.
Now, I want to make sure that whenever the user hits the 'Back' button in the navigation bar, the next time around when he drills down to the flippable view, this view is in its original, non-flipped position. Currently, the app actually loads the correct view, but somehow, when you try to flip it over, it cannot doesn't load the flip view, and presents a black background only.
One solution could be to assign the flip back method ("showLessInfo") to the navigation button, and that is what I need your help for.
Alternatively, and quite likely a better idea for me would be to understand, why the flip view is not loaded the second time around.
Any suggestion is welcome!
You can override the viewWillAppear: method on your flip view's view controller and make sure behind the scenes it loads the proper view before showing (remember to call [super viewWillAppear:animated]).
Or else, you could override the viewWillDisappear and make sure things are cleaned up on the way out. It will get invoked when the user taps the back button.