Group table view with multiple text fields - iphone

I have a group table view with 10 sections, each section has one cell, and each cell has a text field inside.
When user tap on a text field I scroll its parent cell to bottom, so that it will be exactly above the keyboard.
Every text field has a "Next" return key, so when user tap it the next text field (in the cell below) should be first responder.
The problem is:
Suppose user tap on a text field of cell at index 5, this will make the keyboard pop up and the tableview will scroll so this cell will be right above the keyboard.
Now user press the next button..
What I want to happen is to make the text field of cell at index 6 become the first responder.
But how do I get this text field??
If I try to get the cell with cellForRowAtIndexPath I'll get nil, because the cell is invisible..

Two solutions come to mind:
1) you don't have many cells, so don't recycle them, create them when you startup and put them in an array where you can easily get them, Then, when the tablview asks for cells, you pull them out of your array.
When you want to go to next, you simultaneously tell the tableview to scroll to such and such a location or cell, and you pull the cell out of the array, add it to your view with some offscreen frame so it cannot be seen, and make the textField the first responder (to keep the keyboard up). when the tableView asks for the cell, you MAY need to reset the frame, or both reset the frame and remove it from the view. If you find you need to do this you MAY need to make it the first responder again soon (dispatch a block to the main queue so that the text field never resigns first responder.
2) Similarly, when you want to make a cell's textField the first responder, and its contained in the visible cells, then you can just scroll and make it the first responder. If its not in the visibleCells, create a cell, add it to the view as above, do the first responder stuff as above, and when you are asked for THAT cell's index, supply that cell, possibly resetting the frame.
I've used offscreen textFields to play tricks with the keyboard (to keep it up, to get it up, etc - so I know that works). What's less certain to me are the tricks with the textField being in the view or not.
This makes me think of a 3rd way. You put a UITextField offscreen in the view. When you want to switch, and the cell is not yet visible (that is, created), you tell the offscreen textField to be firstReponder, then track the tableView scrolling, and when it ends the textField you WANT s first responder is now visible, so you can transfer (ie set) firstResponder on it, keeping the keyboard up.

I do not know how you create your rows but you need to consider, that UITableView recycles the cells. That means that the text field could be theoretically the same as before, just the content changes.
So all you need to do is make sure you know the textfield that is positioned right above the keyboard. I would not be surprised if this will be created when the view enters and never actually changes.
Again, the table recycles the cells and their content holders only filling in the corresponding data for the row as you provide it.
If you post your code that creates and recycles the cells I could be more specific.

Related

Closing UITableViewController when the keyboard covers cells causes crash

I have a UITableViewController with custom cells for static and editable text. Standard stuff, nothing fancy.
The cell data is stored so that when cells are reused, the data is placed back inside them.
The problem is this: when the user has the cursor in a UITextField cell and the keyboard's up, the keyboard is covering three rows in the table view. There's a cancel button at the top of the view controller which is supposed to dismiss the view controller. When I call dismissModalViewController, the keyboard hides, but the UITableViewController wants to refresh the rows that were under the keyboard while the view's going away. However, the view's already in its death throes and I get a crash because the table view's trying to call cellForRowAtIndexPath to update rows that are in the process of being removed.
I tried waiting for the keyboard to hide. No good.
I tried resigning the first responder so the keyboard goes away and updates the rows first before dismissing the view controller, but there's nothing I can find that tells me the data's finished updating.
What I need is some event that tells me that the table is finished updating, or tell the table view to not ask for data from the delegate, or tell the table view to not update when the keyboard is going away.
Or there's something simple I'm missing.
Any help?
If you have not more cells, i advice you to make a different Reusable Identifier for each cell.That very better to save the state of cells after being dequeued
I solved my own problem. Inside cellForRowAtIndexPath, I was setting text inside a UITextField for pointers that may no longer exist. What I did to fix the problem was still create the cell, but before setting the text inside it, I checked if the Cancel button was pressed and if it was, return the empty cell.
I was hoping there'd be a better solution such as waiting for the cells to finish updating, but that doesn't seem to be happening.

image is reverting to original when scrolling uitableview

I have a button inside each cell. When it's pressed, the image is changed (basically a checkbox) to denote a selection. When you scroll to the bottom ... then scroll back up to the top. The image is reverted to the original image.
This question is pretty similar to this:
Preserve Cell Image After Scrolling UITableView
And others. But, I can't seem to find a good answer. I understand that's it's reverting back to how the uitableview is setup when the cell goes off the screen. But, how do I save the changed image to the uitableview so when it scrolls it doesn't revert to the original?
Thanks in advance! =)
It's changing back because cells are reused. When your cell is going off the screen it is taken out of the view and put back into the reuse pool. Then you're getting it out of the queue again in cellForRowAtIndexPath and setting it back up as the default.
The question you linked to is exactly what you should follow. You should store the state of your cell in your view controller and then when you set it up again in cellForRowAtIndexPath you should load that state and set up the cell appropriately.
One simple way for your method would be to have an NSArray which you set up to be the same size as the number of rows in your table and then in that just store an NSNumber for each row which contains a boolean value on or off for your selection state. When the user toggles, toggle the value in the array and then in cellForRowAtIndexPath read that value and set it up appropriately.
I'm assuming the checkbox in your table view cell is changing state to a selected state because a user selected it. You shouldn't use UI elements to maintain the state of your app. That is, when the user taps the checkbox, you should use that event to somehow reflect that state change in a data object in your app. Then, when that cell needs to be displayed again, you configure it with the state you previously saved. This allows for things like cell reuse, and view unloading and is all-around a good habit.

Trying to make a Custom UITableViewCell with a UITextField becomeFirstResponder when Editing

I have a UITableViewController with custom UITableViewCells that contain a UITextField. When switching the table view into edit mode, I add a new cell to the bottom of the table and would like to make this cell becomeFirstResponder. My tableView:cellForRowAtIndexPath: method checks for this bottom cell, so I just added the line:
[cell.theTextField becomeFirstResponder];
Which I believed should work. However, when the table view is first displayed, it does not seem to be working. BUT if I select the cell (making it the first responder), then go out of edit mode (causing a resignFirstResponder within my code), I can then go back into edit mode and magically it becomes the first responder as I would expect!
Note that even if I end editing mode with a different cell selected (they all have text fields) and go out of edit mode, then back in, it still works, as long as at some point I had made the last cell becomeFirstResponder (by selecting it).
So, my guess is that when it first becomes the first responder, there is something getting set either in the table view or some place else that wasn't originally set, and from then on it makes this work.
Anyone have any ideas as to what may be going on here?
The first becomeFirstResponder call fails because the cell doesn't have a superview yet. The table view adds the cell as its subview after you return it from tableView:cellForRowAtIndexPath:. I suggest you make this call somewhere else. If you already have a custom UITableViewCell subclass, you could implement didMoveToWindow: and call [self becomeFirstResponder] there.

Prevent keyboard from moving textview in UITableView

I have 2 cells in a group in a tableview, the first has a textview in it, (2 lines max). When the user selects the textview, the keyboard appears and moves the textview up from under the keyboard. the second cell only appears when the textview has focus.
However the second cell is still hidden by the keyboard, I have tried to the various methods that scroll the tableview, but the result is always jerky, with the table moving up and down rapidly. Probably because its inserting a row, scrolling up for the keyboard and me trying to make it scroll up even more all at once.
How can I prevent the keyboard from moving scrolling the table view at all, so that I can do the scrolling myself exactly how I want it, and avoid the ugly fight between the two methods.
Did you try this method by setting scroll position to UITableViewScrollPositionTop ,if this not work ,just make your second cell that with textfield :)
- (void)scrollToNearestSelectedRowAtScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated
Use a UITableViewController instead a UIViewController (for the ViewController where your UITableView is placed). That will solve the scrolling issue.
If not possible, you have to scroll by your self (pain in the ass).
See: Making a UITableView scroll when text field is selected

Manually scrolling UITableViewController when a UITextField becomes first responder

Harrr pirates!
I'm trying to make a data entry screen using a UITableViewController. It contains a grouped table view with two sections, each with a few (2 and 4) rows with a UITextField inside them.
When any of the UITextFields become first responder they scroll into view automatically. Great, you would say, but I want to scroll the whole section into view, not just the row containing the UITextField that became first responder.
I don't allow the user to scroll the UITableView by hand and I know to what position it should scroll to display correctly. However, I can't get my UITableViewController to stop automatically scrolling the UITextField into view for me.
Searching StackOverflow I can find a lot of questions about how to resize the UITableView when the keyboard appears, but this doesn't stop the automatic scrolling.
Any suggestions? Your help would be much appreciated!
TableView is basically an extension of scrollView therefore if you want to do the scroll yourself you should use the scrollview API.
Set the contectSize property to the size of the screen without the keyboard and the contentOffset to the location on the table you want to scroll to