How can I get UILabel on a custom table view cell? - iphone

In my custom cell there is a UILabel and one UIButton. Whenever I click on that UIButton the UILabel's height is increased as per content of the label.
The problem is that how can I get that UILabel that is a subview of a cell. Every cell contains a label and a button but only that UILabel is increased that the cell button is clicked, others remain as they are.
Thanks in advance.

You can go through all subviews in the cell and see which one is a UILabel:
for(UIView *v in [cell subviews])
{
if([v isKindOfClass:[UILabel class]])
//you can put more checks to see if height is to be increased/decreased
[v setFrame:CGRectMake(origin.x,origin.y,width,height)];
}

For this you have need to assign TAG for every component..

Try bind the method to your button may work for you.
-(void)buttonClick:(id)sender {
UITableViewCell *cell=(UITableViewCell*)[sender superview];
NSArray *subviews=[cell subviews];
for (int i=0; i<[subviews count]; i++) {
id object=[subviews objectAtIndex:i];
if([object isKindOfClass:[UILabel class]]){
//do stuff here
}
}
}

The easiest way is to assign the tag property to the labels. That way in your button action method you can find the relevant label. For example:
- (void) myButtonAction: (UIButton *) sender
{
UILabel *theLabel = (UILabel *) [sender.superview viewWithTag: MYLABELTAG];
// Do something with theLabel
}
What this code does is finds the label in the same view as the button is in.

I wrote a short example on how to get labels from tablecells here: https://stackoverflow.com/a/9864169/407488
But i think what you want is to increase all labels in all cells at once? Then just use reloadData and change a member variable before calling it (when touching the button). You read that member in your cellForRow: code and assign the height appropriate.

Related

Table Cell SubView Iteration Not Finding TextField

I've created a table where each cell holds both a text label and a text field. I'm adding the textfields as such [cell addSubview:passwordField]; and from a visual perspective they appear and are editable, etc....
The problem arises when I attempt to retrieve the entered values from the textfields. I iterate over the cells and try to grab the subview (IE the textfield), however, my iteration only discovers the text label.
Here is the code I'm using to search:
for(NSInteger i =0; i < [tableView numberOfRowsInSection:0]; i++){
NSIndexPath *path = [NSIndexPath indexPathForRow:i inSection:0];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:path];
UIView* subView = [[cell.contentView subviews]lastObject]; // I've also tried object at index here
// Anything beyond this is just matching....
Another approach I took was recursively searching the subviews, but, again that yielded no results.
You have added your textField on subView of cell.
[cell addSubview:passwordField];
While you're trying to find it on cell.contentView.
Add your textField as a subView of cell.Contentview
[cell.contentView addSubview:passwordField];
And find it in this way -
for(UIView *view in [cell.contentView subviews])
{
if([view isKindOfClass:[UITextfield class]])
{
UITextField *textField = (UITextField *)view;
NSLog(#"%#",textField.text);
}
}
Why not have a datasource mapped to the TableView and just retrieve / update the values in the datasource. You can then call reloadRowsAtIndexPaths to load just the row you just changed. Trying to iterate through the TableView rather than just updating the datasource seems very inefficient.
Instead of UIView* subView = [[cell.contentView subviews]lastObject]; you can try to find it as:
for(UIView *view in [cell subviews])
{
if([view isKindOfClass:[UITextfield class]]){
// view is the reference to your textfield
}
}
That way you can add other UIViews as subviews and still get the reference of the textfield without having to keep track of its subview index.
2 things occur to me:
In the long run it'll be easier to create a UITableViewCell which contains a UITextField which is accessible as a property. You can either use a nib to layout the cell or do it programmatically in the cells init method. This approach will make your code easier to manage.
You need to consider cell reuse. If you are reusing cells (which you should be) then you will need store the fetch the value from the textfield before it is reused.

how to clear the dynamically created UITextfield values in IPhone?

I Created five UITextField using for loop i want to clear the textfield values when i Click the Clear button but only clear the last textfield values.i want to clear all text fiel values how can i solve this any one Help me Thanks
In your clear method write like:
for (UIView *addedView in [self.view subViews])
{
if([addedView isKindOfClass:[UITextField class]])
{
UITextField *myText = (UITextField *)addedView ;
myText.text = #"";
}
}
Here each sub view is taken from the self.view and check if it is a UITextField or not. If it is a UITextField then we set #"" to it.
for (UIView *view in self.view.subviews)
if([view isKindOfClass:[UITextField class]])
[(UITextField*) view setText:#""];
You can do this by using following:
-(void)loopMethod
{
lastTextField.tag=100;
}
-(void)buttonClick
{
UITextField *textField=(UITextField*)[self.view viewWithTag:100];
textField.text=NULL;
}

UITableViewCell with custom UIButton

I am trying to create a UITableView with a custom UIButton in each table cell. I implemented like this..
#implementation CouponDetailsCustomTableViewCell
...............
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
[self setBackgroundColor:[UIColor whiteColor]];
CGRect frame = self.contentView.frame;
self.radioButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.radioButton setImage:[UIImage imageNamed:#"radio_blank.png"] forState:UIControlStateNormal];
[self.radioButton setImage:[UIImage imageNamed:#"radio_selected"] forState:UIControlStateSelected];
[self.radioButton setFrame:CGRectMake(16, 10, 29, 29)];
[self.radioButton addTarget:nil action:#selector(radioButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:radioButton];
}
#end
and UITableView Delegate as......
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *COUPON_CELL_ID = #"CouponCell" ;
CouponDetailsCustomTableViewCell * couponCell = (CouponDetailsCustomTableViewCell *) [tableView dequeueReusableCellWithIdentifier:COUPON_CELL_ID];
if (couponCell == nil) {
couponCell = [[[CouponDetailsCustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:COUPON_CELL_ID] autorelease];
couponCell.selectionStyle = UITableViewCellSelectionStyleNone;
}
[couponCell.radioButton setSelected:NO];
return couponCell;
}
and the radioButtonPressed method is
-(void)radioButtonPressed:(id) sender
{
[sender setSelected:YES];
}
Now i run the program and a custom UIButton is shown in every table row . If i click on a button it gets selected (shows the radio_selected.png).
The problem arises when i scroll down the table (i am showing only 4 rows of the table in the window) . When i scroll up again..what i see is the clicked button is showing the radio_blank.png.
I am new in iPhone development. i dont know why is this happening. The most i can guess is the button property is changing .. setSelected:NO.
Someone please give me suggestions to fix this problem.
Thank you.
When you scroll your UITableView, hidden cells are not rendered anymore and might be reused for cells that are becoming visible. If a new cell becomes visible, tableView:cellForRowAtIndexPath: gets called.
The problem is that you're setting the selected state there:
[couponCell.radioButton setSelected:NO];
Therefore, whenever you scroll your cell out of the visible area and back again, it gets reset to selected = NO.
I suggest you create a NSMutableDictionary where you store the selection state of each row/NSIndexPath, which you then re-apply in tableView:cellForRowAtIndexPath:.
replace [couponCell.radioButton setSelected:NO]; in tableView:cellForRowAtIndexPath: with code that sets the selected property depending on a state from your dataSource.
something along those lines:
/* get the button state from your data source */
FancyCouponObject *coupon = [self.coupons objectAtIndex:indexPath.row];
BOOL buttonState = coupon.buttonState;
[couponCell.radioButton setSelected:buttonState];
The cells of a tableView are reused when they are moved off screen. You can't save state in them.
problem is when you scroll the table at that time your cellForRowAtIndexPath: delegate method called for every row... so here when its called at time your setSelected Method call with NO argument like bellow...
[couponCell.radioButton setSelected:NO];
so when you scroll table at time your setSelected method call and your button turn with radio_blank.png
...
:)
-(void)radioButtonPressed:(id) sender
{
[sender setSelected:YES];
}
in this method you are setting button as selected and for selected button you have set the radio_blank.png image

UITableViewCell from contentView subview

I have created the cells with labels and using checkaMarksAccessory. The few last cells have UITextFields which can user modifi, and those have selector on UIControlEventEditingDidEnd where i want change the state of the cell to checked.
How can i get the cell in the selector? Doesn't have the object some parentView?
The way i inserting the object to cell.
UITextField *textfield = [[UITextField alloc] initWithFrame:CGRectMake(10, 25, 200, 30)];
[textfield setBorderStyle:UITextBorderStyleRoundedRect];
[textfield addTarget:self action:#selector(vybavaDidFinishEdit:) forControlEvents:UIControlEventEditingDidEnd];
[cell.contentView addSubview:textfield];
I'm not sure if it's safe to assume cell.contentView.superview == cell. Might Apple change this? I doubt it. But, I don't see anywhere in the documentation that says a cell's content view is a direct subview of the cell.
If you've added a UIGestureRecognizer to one of your subviews of the cell's content view, then you can get a reference to the cell with:
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:[gestureRecognizer locationInView:self.tableView]];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
Table View Animations and Gestures sample code uses indexPathForRowAtPoint: this way.
If you must traverse superviews, I think using a function like the one below is a bit safer.
UITableViewCell *ACMContentViewGetCell(UIView *view)
{
while ((view = view.superview)) {
if ([view isKindOfClass:[UITableViewCell class]]) {
return (UITableViewCell *)view;
}
}
return nil;
}
But that function still assumes contentView is within its cell, which I also didn't see anywhere in the documentation.
So perhaps, the best solution is to rearchitect your code so that you don't need to get cell from contentView, or if you must, then add an instance variable from the subview of contentView to cell.
ok so the way is to use superview. The superview is component which own the object. If i want get the UITableViewCell from UITextField i used [[UITextField superview] superview].

iphone tableview cells with custom textview - get textview reference

I have a UITableView with 15 cells, each with a separate text box in it.
I have implemented UITextViewDelegate and I am able to received changed textview data using textViewDidChange (etc). But I have one big problem still, how do I know WHICH textview sent this, (i.e. in which cell was the textview altered?)
Its interesting to have so much working, yet not know precisely where it comes from.
A whole bunch of code is available if required.
Regards #norskben
Code
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
//Big Text Box
UITextView *detailLabel = [[UITextView alloc] initWithFrame:CGRectMake(30, 80, CONST_Cell_width, 150)];
detailLabel.tag = 20;
[cell.contentView addSubview:detailLabel];
}
UITextView * detailLabel = (UITextView *) [cell.contentView viewWithTag:20];
You can assign tags (integers) to the different views and query the tag number to see which view called the method. Look for the tag property on the view:
tag
The receiver’s tag, an integer that you can use to identify view objects in your application.
#property(nonatomic) NSInteger tag
see here
Not at my development machine, but when you create the UITextView you should be able to assign it a tag. I think it is [myTextView setTag:x]; where x is an integer.
Then, in the TextViewDidChange use
if (textview.tag == x) {
//do something
} else if (textview.tag == y) {
//do something else and so on
}
Hope that helps a little.
The text views pass a reference to themselves in every delegate method so you know which one sent it. To make a connection to the cell, I'd set each text view's tag property to a different value that corresponds to the row of the cell they're in.
Here's an important question: Are your text boxes static, or can they change over time? If they won't change (the user can't alter the number of cells or add more later), then you can declare a new textField for each cell. I have something similar in my apps. I have two text boxes, and depending on which textField is currently active, the delegate does something different.
Declare separate text fields in your header
UITextField *textField1;
UITextField *textField2;
UITextField *textField3;
in the delegate method, use if statement blocks to find out which textField is changing:
if (textField == textField1) {
//do something
} else if (textField == myTextField2) {
//something else
}
Note that this really only works if your view is static.
Hope this helps
Have a great day
When you're searching the UITableView's cells for the event source UITextView, only iterate over the cells that the user can currently see. This can be obtained using the following UITableView method:
- (NSArray *)visibleCells