I have a storyboard, which includes navigation between views. Back and forth, and there is also the possibility to jump all the way to the home screen.
Basically, it works like this:
View 1 shows a simple menu.
View 2 shows input fields and automatically shows the keyboard.
View 3 shows a results table. In this view one can go one step back (to view 2) or back to the home screen (view 1).
The keyboard and everything works perfectly the first time, when the user moves from view 1 to view 2. However, when moving either back from view 3 to view 2, or from view 3 and starting all over again, the keyboard does not show.
In the code, I have becomeFirstResponder in the viewDidAppear method. Also, it will resignFirstResponder when loading view 3. Another interesting fact is that when calling the becomeFirstResponder for the second time, it does return NO (while it returns YES the first time). Also, when returning back to this view the textfields are not possible to select, even though they are userInteractionEnabled.
I am really stuck here, so any help is highly appreciated.
I have seen several similar questions to this one, but not found a solution:
becomeFirstResponder seems to work only 1st time for shake gesture
Adding [myUITextField becomeFirstResponder]; does not bring up keyboard
keyboard not responding to resignFirstResponder
UITextField becomeFirstResponder works only once
I was able to track down the problem in my code. Answering this question myself since it might be helpful to others as well.
My issue was that I didn’t really get the order of events correct. I had a button that would move to the next textfield, and if everything was completed it would move to the next screen. This caused the becomeFirstResponder method to be called and not released (resignFirstResponder) when switching to a new screen.
I guess the main advice I can give (at least what finally worked for me), was to just go through all the becomeFirstResponder and make sure it is released before moving to next screen.
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.
I'm working on trying to figure out storyboards and it all seems pretty cool but I'm having problems with moving from one screen with a few buttons to another screen no matter which button is pressed. Obviously I can control drag from each button but then I have segues all over the place on the story board and I feel like there has to be a better way to do it. I've tried highlighting all the buttons and control-dragging to the next screen but that only caused the one I dragged from to work.
Here's an illustration of what I have that works right now...
If I have to stick with this then so be it but I'm going to end up with 6 buttons on one page and 8 on another. That's alot of segues. Basically each button signifies a choice for the user. That choice will cause different things to happen behind the scenes but no matter which button they choose they move to the next screen.
What I've Tried:
Highlighting all the buttons and then dragging to the next view controller.
This failed because it only connected the segue to the button I clicked on when I control-dragged
Dragging out one segue then dragging from the second button to the circle part of the segue.
This caused nothing at all to happen.
I'm unaware of a way to give a single segue multiple triggers in a storyboard, however you could create a single segue with a particular identifier, and then have all of the buttons respond to a single IBAction that calls [self performSegueWithIdentifier:...];
Check out generic segues, which are tied to the source view controller instead of an IBAction:
https://stackoverflow.com/a/8868096/295130
Not sure what's going on here, but my iPhone apps nav bar shows back and the title of my detail view controller even when I'm back to the original view. It wasn't happening earlier, it has changed recently (but not sure when exactly).
E.g. I click on a row, view the didSelectRow XIB and then click back on the NavBar controller, but it still shows back even though the view does change back to the original table view. I then have to press back again and then it clears.
Update: It's as if its trying to go back three times instead of two. Because, if you visit another row without removing the back button, it stores it as if you need to go back twice.
It works fine in portrait mode.
Any ideas?
Not all the tables had been set to auto-rotate, so their views were still staying portrait.
I am looking for a way to show my own input view (a UITableView) to enter certain keywords in a UITextView faster than typing them, and also be able to type into this text view the normal way. My solution has a button that causes the keyboard to disappear, revealing the table view underneath it.
Problem is I can't figure out how to make the keyboard go away without resigning first responder, and losing the cursor. Has anyone accomplished this before?
Thanks for any help.
Nope
As far as I know there is no way to do this, and I have searched extensively. Very frustrating that selection and the cursor are restricted to the keyboard.
I could be wrong though. Votes? Suggestions?
You can call becomeFirstResponder on some other thing that you choose. It could be a UIViewController or a UIView. I had a similar problem before, I needed to make my keyboard go away when I was pushing my view controller back to its caller, without knowing which textfield was the first responder. Then, on viewWillAppear of my view controller which I was returning back, I called [self becomeFirstResponder] and the keyboard of the pushed view was gone. Because this made whichever text field was it loose being the first responder.
The scope of this question is IPhone 3.1 sdk (app running in simulator still)
I have a table view that has a cell with a UITextField in that cell. The table view is grouped, and has one section with just a couple fields. Im NOT using IB so backgroundTap is out of the question (as far as i can tell at least). When i click the text field, keyboard shows. Hiding it is still troublesome. Ive pulled the UITextFieldDelegate into the mix to hide the keyboard but the textFieldShouldEndEditing method doesnt seem to fire when the background is tapped (when i mean background, im tapping outside of the grouped table view section). First off, should it?
textFieldShouldReturn fires with no problem and i can resign at this point but shouldnt i be able to resign if focus shifts away from that control?
Any help is much appreciated
-me
Generally you'll only stop editing a field when you:
hit the "Done" or action button on the keyboard
begin editing another field
exit the view
have another button on screen that removes focus
From any of these, you can call -[textField resignFirstResponder] to dismiss the keyboard and call your -textFieldShouldEndEditing: method. There's no reason that just tapping on a non-active part of the screen should dismiss the keyboard.