I have a view controller with a table view and a UISearchBar. When the view controller is first brought up, the table is populated. A click on a table row pushes another view controller, it animates up and then pops right back down and returns me to the table. It does this whether the search bar has been used or not. I do this push pop kind of action in several view controllers with not problem. My guess is that the UISearchBar is somehow getting in the way. Any one have any idea as to what I'm doing wrong?
Check your viewDidDisappear code, or anywhere else you might have a popViewController. Betting one is getting called somewhere.
Related
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.
What I am asking may be impossible and sound weird, but here it goes.
Here is similar to what I want to achieve:
A user opens the app for the first time, there are two tab bars, in the first one (he has not tapped the second one yet) he presses a button that should initiate a progress view and text view changes and other view changes EVEN THOUGH the user has not loaded the other view controller by clicking the second tab bar.
So, is there a way to generally load a view controller before the user manually loads it himself, I know calling viewDidLoad manually will not help, any suggestions? Pretty confusing, it is like modifying a view but the controller has not loaded yet...
Thanks!
Make the changes in the other view controller and then let the controller configure its own view when it does its natural loading.
Sorry I can't show code for this question - it should be fairly simple to explain..
I have an array of data (object1, object2, object3, etc)… I have one tableview that lists these objects (object1.title, object2.title, etc) and upon clicking it push's a viewcontroller that shows the detail of each object. Now, rather than have to press Back on each detail view, I'd like to put a next button on the detail page..
I could easily push a new controller, however it would end with a chain of:
List View -> Detailview1 -> Detailview2, etc..
which would be a pain to traverse back up the stack.. Can the parent view controller be removed / changed easily or is this not the best way to do it?
Cheers.
You can always pop back to a specific index in the stack. So you could have a back button that pops back to the parent. If there is no real reason that the user would need to go back through the detail view controllers you could swap controllers by replacing the stack with a new stack using setViewControllers:animated: Look through the UINavigationController documentation and see whats possible.
This code will "pop" the view contoller off the view, so it removes it, instead of overlaying another view on top of it. Add this to your button action
[self.navigationController popViewControllerAnimated:YES];
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 looking for some kind of solution to a problem I have.
I have a main view controller. On this view controller I have a button it works well most of the time. But when i pop up smaller view controller onto my main view controller, a part of the small view controller is behind the button.
So the button is is still on the front of the sceen, with the small view controller behind it.
The small view controller seems to take the key presses that were ment for the button. Is there a way to get the button to take the keypresses? I though it having the higher z order would make this so, but obviously not. Is there a work around of this?
Or am I going to need to have an invisible button on my small view controller that calls back to the parent view controller to say the button was pressed.
Many Thanks
C :)
Key presses go to the first responder of a window not the frontmost view in the z order. So after popping up the small view controller make the button first responder then key presses will go to it.