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.
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 have a view controller with user content like text/images/location data and i would like to duplicate the viewController and present it modally (presentModalViewController) when the user taps the edit button. The reason for doing this is because i want it to be clear that the user is entering the edit mode by using the transition/animation that comes with a modally presented controller.
Does anybody knows how to duplicate an entire viewController + its view? i don't want the overhead of reallocating the entire viewController. I tried a couple of things, but i haven't had any luck.
Any help/information would be welcome.
That sounds a little impractical. You could make an image of the current screen contents, present that using whatever animation you like on top of everything, and then remove it?
Or make other changes to your view (rearrangement of views, appearance of other controls, changes of colour) in your viewController's setEditing:animated: method.
I have a navigation controller with a UITableView which when goes to another view when a row is selected. When this loads the breakpoints get hit.
Good so far.
When I hit the back button, the table view appears fine, with data.
However, even though I have breakpoints enabled in the viewcontroller, none get hit like when it originally loaded! But yet, the data loads fine. The only breakpoint that registers now is when I click on a row (didSelectRowAtIndexPath).
Where are the breakpoints set that you are expecting it to break?
Perhaps you need to call the following in the viewWillAppear method...
[self.table reloadData];
It would depend on where your breakpoint is actually located. If you have a breakpoint in viewDidLoad method, then it will only be called once when the view is first created. When you go back from another view, the view is not loaded again. So the breakpoint will not hit. However, viewWillAppear method will be called.
You are using a navigation controller here. Navigation controller holds a navigation stack, which includes UIViews on top of each other, with the visible one on the top.
Now, let's say the table view was loaded, then you move to another (which is now the topmost view in the navigation stack). Note - the table view is not gone. It's there, just under the view you are currently presenting.
Thus, when you move back to the table view, it is not reloaded, because it was never gone (released), just hidden.
There are exceptions to the above, and sometimes a view which is not presented on screen will be released (low memory scenarios situations, for example), but you can't count on it.
The UINavigationController Class Referance explains this concept very well.
I'm writing an iPhone app using Appcelerator Titanium Mobile. I am hiding and showing the tab group based on what window has focus.
dashWin.addEventListener("focus",function(e) {
if (dashWin.tabGroupVisible == true) {
dashWin.tabGroupVisible=false;
tabGroup.animate({bottom:-50,duration:500});
}
});
The code above hides the tab group when dashWin receives a focus event. However, I see this message in the Titanium console when the event fires while running in the iPhone simulator:
Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
A Google search turns up one result: Another StackOverflow question that may have a hint as to what's going on.
I got this error when I linked Action Segue or Selection Segue from one view to another view through storyboard and performed the same segue programmatically again, which makes the navigation controller perform the same segue twice.
2 solutions for this case:
Removing the code that pushes the view. Just let storyboard perform the segue for you. This is good for most situations.
Replacing Action Segue or Selection Segue with Manual Section and do - (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender by yourself. You may find this solution useful when you want to customize the behavior of segue according to the sender.
Usually a tab group acts as the root of your app's navigation. When a user taps a tab, that tab's window is focused.
Next, when a user triggers an action that requires a new window appear, it usually appears either modally or on top (in the navigation stack sense) of the current window. In the latter case, tell the current tab to open the new window.
If you set the tabBarHidden property to false (when you create the new window), the tab bar will be hidden for you when the new window is opened by the current tab.
Will this more standard approach work for you?
I had segues that were leading back to my main navigation controller which was causing this. I fixed the problem by setting the main navigation controller back to the top of the stack. Here is the code:
- (void) viewDidAppear:(BOOL)animated
{
[self.navigationController popToRootViewControllerAnimated:NO];
}
Recently, I've faced the same problem. The reason was:
-I was trying to pop view controller twice by mistake.
you can check this crash by setting breakpoints on push and pop View controllers
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.