Change properties of UILabel in a TableViewCell - iphone

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

Related

How to set the height of subviews of UItableViewCell when cell is created programaticalliy

I have custom cell created with nib. In the table view I am using the method -(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath to set the height of cell
Everything works fine.
But the problem is that I also want to change the size of UIlabel which is added as subview in nib of cell.
How do I do that?
Which metod to override in customcell class ?
The method you are looking for is:
-(void)layoutSubviews
{
[super layoutSubview];
//Do your magic
}
layoutSubviews is call after the cell is created and whenever the device orientation changes, to allow you to resize and/or move the subviews (plus make any other minor adjustments) to compensate for differences between the orientations, but in this case you can also use it to redraw your subviews.
As you have UILabel in your custom cell class, make a function in that class that take frame you want to set as parameter. Set frame of label in that function. You need to call this function from your cellForRowAtIndexPath method before returning the cell.
If you are reusing your custom cell you should call method only when the (cell == nil)
Also if you can add some code in your question that would be helpful and you can get more precise answer.
You need to treat your custom cell in the same way you would treat a normal view or view controller class with a xib. i.e. You need to create IBOutlets for the controls in you custom cell and during creation of the cell you can access the controls quite easily.
myCell.myCustomUILabel.text = #"blah"
There are some gotchas when using custom cells in a xib and onnecting up the IBOutlets. This SO answer (of mine) explains how to create and link up IBOutlets of a custom cell.

How to insert more than one piece of a data into a single cell of UITableView

I am interested to know how to add more than one piece of data into one line of data into a cell of UITableView.
For example in the StopWatch of the Clock App in Iphone, they are able to have more than one piece of data.
Lap Time Total
1 00.01.5 00.01.5
Interested to know how to add three values into one cell at a time...
You'll need to create your own cell, which inherits from UITableViewCell.
Here's an example of how to create your custom UITableViewCell.
You would have to create a custom uitableviewcell for that checkout this tutorial or refer to Apple Documentation for more detail
You could either subclass UITableViewCell, or you could choose the "Custom" attribute on IB on the cell, and drag and drop labels, buttons, and whatever you want into the UITableViewCell. Set tags on each IBOutlet you create. Then you can do like this in tableView:cellForRowAtIndexPath
UILabel *yourLabel = (UILabel *)[cell viewWithTag:tag]; // Set your own tag and outlet.
From there you can customize it just how you want, without having to subclass it.
When that is said, the usual way is to subclass UITableViewCell. That way, you can have each cell store information, and add the IBOutlets as properties to the CustomTableViewCell as normal. Then you could add the information to the CustomTableViewCell, and let the cell take care of the rest.

How to have an editable multine UITextView in UITableViewCell

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.

UITextView in UITableViewCell subclass, how to keep the data separate from the view

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 =)

Setting UIPickerView selection to UITextField inside a UITableViewCell

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.