I have a UITextField in a custom tableview cell. On tapping the textfield area I display a popover which contains a pickerview. I need to set the selection from the pickerview to the textfield's text. I show the popover from the textDidBeginEditing method. How do I pass the selection from the pickerView's didSelect method to the textfield?
By design the entire thing is in a TableViewController with the textfield and pickerview delegate methods implemented.
Thanks!
Just set the UIPickerView's delegate to be the viewcontroller that has your UITableView. That way on the UIPickerView's didSelect (implemented in the tableview's viewcontroller) you would simply use the pickerview's datasource to populate the textfield.
To get your custom cell from a tableview you simply do:
CustomTableViewCell *thisCell = (CustomTableViewCell*)[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:section]];
Then you set the textfield in that to have whatever text you want:
thisCell.textField.text = #"text";
Can you provide a little more information? What's the tableView:cellForRowAtIndexPath: look like? I'm curious where the object you're editing is available.
There are a couple approaches I can think of...
Set the tag on the textField(s) and use it to locate the specific textField being edited
Set the delegate for the pickerView to the tableCell and have it handle the textual change
I believe the best approach is to set the UITextField's inputView property to a UIPickerView. This view will be displayed instead of the keyboard.
When a UITableViewCell is scrolled beyond a table's bounds, it may be deallocated. Therefore, storing a reference to the UITextField which invoked its textFieldDidBeginEditing: delegate method could result in an EXC_BAD_ACCESS exception.
The solution is to modify the cell's model which is stored in an array by the view controller. When the cell is initialized, it should set the text field's value to the corresponding value in its model object. Finally, the cell should observe changes to its model via KVO and update the value of the text field accordingly.
Related
I've got a UITextView inside a UITableViewCell subclass. I have no problem getting the new height of the Text view and cell. The problem I have is telling the UITableView to update.
I have implemented heightForRowAtIndexPath: to return the live height of the cell as the TextView expands.
But somewhere `[tableView beginUpdates]; [tableView endUpdates]; must be called.
How? Should I add a delegate property to the UITableViewCell which is set to the UITableViewController subclass? And then send a delegate message when the cell expands height and the Tableview needs to update? It seems a little weird to have a delegate between the UITableViewCell and Controller?
I tried using NSNotificationCenter, but I have more than one editable cell, and more than tableview of this nature. So there is no way to register only for notifications for the cells without copying and pasting the same line over again, which isn't nice (as the cells are created in IB, and are not in an array or set), and having multiple tableviews means an exception occurs on the other table view as it is told to update but nothing changes.
I've seen lots of questions and answers on this topic, but when it comes to updating the tableview they all just say "now update the tableview" and not how to. So how do I telly he tableview to update, from one of it's cells?
I would think that this behavior would be best implemented in the UITableViewController instead of the view itself (the UITableViewCell).
Your controller is responsible for setting cell height, and typically will be the delegate for your UITextView's, so let it handle all of this.
In your textViewDidChange method, figure out what the new height of your cell should be, update your data structure to reflect that, and call reloadRowsAtIndexPaths:withRowAnimation: to have it actually change.
Edit:
So since you didn't like my first suggestion, another way to do this would be to add a recommendedRowHeight property to your custom UITableViewCell.
Then, you can either observe this property from your UITableViewController or implement a delegate protocol with a method along the lines of:
- (void)recommendedRowHeightDidChange
// or
- (void)recommendedRowHeightDidChangeTo:(CGFloat)newHeight
Then, when your height changes, update your recommendedRowHeight property and call your delegate's method if you go that route.
Either way, once your controller figures out that the recommended row height of a cell has changed, it can do what it is supposed to do. Update your data structures reflecting the current row heights and then call reloadRowsAtIndexPaths:withRowAnimation:.
You can add your tableview controller object as a weak reference to your tableview cell class. And in tableview controller you can have a method which will be called from tableview cell class.
So I don't know what the best way to follow MVC is. Similar to the address books app, I want to have a UITableVeiewcell that has the ability to edit notes. I figured I would do that with a UITextView in a UITableViewCell subclass. My subclass has just that as a property, and a label that says "notes". I can see a few use cases that I need to consider,
1) when they are done editing and click outside or hit return.
2) when the text goes beyond the size of the cell I need to resize the cell.
Because my UITextView is in IB, is there a good way to define the delegate methods for the UITextView since my UITableView is in another ViewController subclass? Like how do I pass that information back?
Or, is it better to create my UITableViewCell subclass in code since it's just a couple of items so all my delegate and resizing code is done in the view controller class?
Thanks!
After text field editing was finished, you can store it's value in some dictionary in your controller. You can use cell's indexPath as key in this dictionary. In such way you will not lose your data with dequeue cells.
To resize cell you must call reloadData method and change rowHeight property of entire tableView or implement tableView:heightForRowAtIndexPath: delegate method to set needed row height to current cell.
I haven't use UIKit since iOS 3.1, so the second part of my answer can be out of date, but I hope it will help you =)
I have a tableview with each cell loaded from a xib. It is in the format UILabel some space and UITextField. On a button click somewhere on the view I need the action to fetch all the textfield values in the UITableView with the labels in a dictionary. The problem is when I alloc a cell and fetch the values from there using indexPath, the code crashes exactly at the indexPath of the cell which is invisible (out of screen bounds).
I would appreciate any good ideas on how to fetch those cells which are not visible on screen.
Thanks!
UITableViewCells are reused when they scroll out of view, so that's probably why it won't let you access attributes of UITableViewCells that are not visible.
An NSDictionary might be your best bet:
Set a tag for each cell's UITextField based on the indexPath.row value during cell creation.
Set the delegate for each UITextField to your view controller.
In the delegate method textFieldDidEndEditing, update your dictionary as such: [dictionary setObject:textField.text forKey:[NSNumber numberWithInt:textField.tag]]
And now you can access an array of your textField values with [dictionary allValues].
I want to read text of a textField inside the tableView Row And Button is also inside the so when user clicks that row textfield data set into database.
Two tactics.
subclass UITableViewCell, add a property for your textField. Then in -tableView:willSelectRowAtIndexPath: you can call UITableView's -cellForRowAtIndexPath: to get the cell. Use the property you added to access the UITextField.
Don't subclass. When you add the UITextField to the UITableViewCell set it's tag property to some unique identifier. Use the same tactic as above to get the UITableViewCell, but then get a pointer to the UITextField by using UIView's -viewWithTag:
I have a tableView that's loosely based on the DetailViewController in ye olde SQLiteBooks. It's created programatically. Each cell displays a single value that when clicked displays a generic editingController that allows the user to edit that value. Pretty standard Cocoa-touch stuff...
Except...I also have a segmented control in the header of said tableView that depending on it's setting needs to change an attribute (textColor) on a UILabel in ONE of the 8± tableViewCells in the table. I have no IBOutlets for this tableView because I created it entirely in code. So, what do I need to do in my (void)segmentAction:(id)sender method (triggered when segmentedControl changes state) to allow me to access & change this value and display it to the user? When the table was built (cellForRowAtIndexPath) every UILabel was called "value" and then added: [cell.contentView addSubview:value].
I've tried setting a property of the viewController itself that is then checked during cellForRowAtIndexPath and does the textColor business there...and then adding [self.tableView setNeedsDisplay] to my segmentAction: method but it doesn't seem to work?!?
Any ideas?
If you know the indexpath of the cell you want to modify, you can call cellForRowAtIndexPath: to retrieve the UITableViewCell. Once you have that, you can get the UILabel from it. If you set the UILabel's tag to some useful value when create it, you can then retrieve it from the UITableViewCell via viewWithTag:.
In the class that implements cellForRowAtIndexPath you could also store a reference to the UILabel that you want when you build the relevant cell.
This would then mean you could alter the label and mark it to be repainted.
Alternately you could hold a local BOOL to show that the cell should be drawn differently - and then use this this in the cellForRowAtIndexPath: to draw it with a background.
You might find this easier with the 3.0 textLabel object in a UITableViewCell