refresh the uitableview contents - objective-c

I have added uitableview in which I am trying to add custom UIButton. It is added successfully with this code:
image=[UIButton buttonWithType:UIButtonTypeCustom];
image.frame=CGRectMake(240, 7, 25, 25);
image.tag=101;
image2=[UIButton buttonWithType:UIButtonTypeCustom];
image2.frame=CGRectMake(240, 7, 25, 25);
image2.tag=102;
if ([outputlabel.text isEqualToString:#"Yes"]||[outputlabel.text isEqualToString:#"Yes"]) {
[image setImage:[UIImage imageNamed:#"tick.png"] forState:UIControlStateNormal];
[cell1.contentView addSubview:image];
[cell1.contentView bringSubviewToFront:image];
}
else
{
[image2 setImage:[UIImage imageNamed:#"cross.png"] forState:UIControlStateNormal];
[cell1.contentView addSubview:image2];
[cell1.contentView bringSubviewToFront:image2];
}
Its working fine at first. When table view reload it overlaps the uibutton old image. I am unable to refresh the whole table with new values. Someone has an idea what I am doing wrong in code.

Updated. Always Create content view for cell in cell == nil block. Use that contentview outside by the tag.. Then only it wont overlap and reuse ur cell perfectly..
if (cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIndentifier];
//Add your button here.. set the tag.
UIButton image=[UIButton buttonWithType:UIButtonTypeCustom];
image.frame=CGRectMake(240, 7, 25, 25);
image.tag=101;
}
UIButton *btn = (UIButton *)[cell.contentView viewWithTag:101];
if ([outputlabel.text isEqualToString:#"Yes"]||[outputlabel.text isEqualToString:#"Yes"])
{
[btn setImage:[UIImage imageNamed:#"tick.png"] forState:UIControlStateNormal];
}
else
{
[btn setImage:[UIImage imageNamed:#"cross.png"] forState:UIControlStateNormal];
}
Just do like this in cellForRowAtIndexPath.. It will helpful for you..

Basically, if we want to refersh the contents of tableview then need to use this reloadData. Did you try :-
[yourTableView reloadData];

Make sure you implement -cellForRowAtIndexPath:. Then refresh your tableViewCells by calling reloadRowsAtIndexPaths:withRowAnimation: on the tableView in question.
The tableView will in turn call cellForRowAtIndexPath, and you simply return the configured cells there.
If you have static cells, you can simply access whatever you need to change by hooking the controls up to an IBOutlet.

Try refreshing your cell's view using
[cell1.contentView setNeedsDisplay:TRUE];
every time you set the image.

I am suspecting, that you adding this images in -tableView:cellForRawAtIndexPath: method.
First of all - if you reusing cell with some reuse identifier, the Cell will stay in memory and will reused when it needed. It's means that all subviews of your cell will be retained. In this case you need to prepare cell for reusing every time. For example - remove all subViews of cell.
But better way, I recommend in case of less number of operations - to create subclass of UITableViewCell and add UIButton as a property of that cell.
Then you will only need to change this property depend of your condition.
if ([outputlabel.text isEqualToString:#"Yes"]) {
[cell1.button setImage:[UIImage imageNamed:#"tick.png"] forState:UIControlStateNormal];
}
else
{
[cell1.image setImage:[UIImage imageNamed:#"cross.png"] forState:UIControlStateNormal];
}
Of course, you button must be added in cell.contentView in the Cell initialiser. Usually it is method -initWithStyle:reuseIdentifier: of your custom cell .m file.

Related

Objective C > UITableViewCell button not depressing

I have the following button being created in the cellForRowAtIndexPath section for this tableView:
UIButton *sched_button_a1 = [UIButton buttonWithType:UIButtonTypeCustom];
sched_button_a1.frame = CGRectMake(0, 0, 110, 52);
CGRect frame_a1 = sched_button_a1.frame;
// Resize height based on length of appointment
frame_a1.size.height = heightCalc;
sched_button_a1.frame = frame_a1;
[sched_button_a1 addTarget:self action:#selector(showAppointment:) forControlEvents:UIControlEventTouchUpInside];
[sched_button_a1 setTitle:[NSString stringWithFormat:#"APPT: %#", APPT_ID ] forState:UIControlStateNormal];
sched_button_a1.layer.backgroundColor = [UIColor redColor].CGColor;
[sched_a1 addSubview:sched_button_a1];
As you can see it's calling showAppointment which is presently just:
-(void)showAppointment:(UIButton*)sender {
NSLog(#"Button pushed");
}
showAppointment is also defined here:
-(void)showAppointment:(UIButton*)sender;
The button shows up fine and gets the correct text and background and appears to be in the foreground, however, when I click on it nothing happens and it doesn't look like the button even gets depressed.
What am I doing wrong or missing?
Edit: I have gone back and removed the sched_a1 view so that the button is directly created in the contentView and this had no effect. It still appears that the only gesture being recognized is the one used to scroll the table. Tapping the button does not appear to change the color of the text or otherwise indicate that the button has been pressed and no log entry is created.
Edit 2: Added cellForRowAtIndexPath to paste bin
http://pastebin.com/WXezfW96
I had a similar issue recently, which I struggled to understand. The solution I came up with was to set the bounds of the button as well and also check for UIControlEventTouchDown rather than UIControlEventTouchUpInside.
Have you tried using cancelsTouchesInView? If you added tap gesture, I think the tap gesture or the tap in table cell overrides the touches in your button. Try using this code:
UIGestureRecognizer *tap= [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(yourAction)];
tap.cancelsTouchesInView = NO;
tap.delegate = self;
[yourButton addGestureRecognizer:tap];
But don't forget to add <UIGestureRecognizerDelegate> in your .h file
But I agree on Mike. Make it short and simple when creating table cell. I think you can use custom cell subclass and xib file.
I'm also new to objective C so if I say something wrong I'm sorry, I'm just trying to help.
UIButton *sched_button_a1 = [UIButton buttonWithType:UIButtonTypeCustom];
in this change UIButtonTypeCustom to UIButtonTypeRoundedRect
Scott, you may want to try my famous troubleshooting technique:
Determine whether the button or the action is the root cause:
UIImage *image = [UIImage imageNamed:#"image.png"];
[button setBackgroundImage:image forState:UIControlStateHighlighted|UIControlStateSelected]
Instead of:
-(void)showAppointment:(UIButton*)sender {
try
-(void)showAppointment:(id*)sender {
Use breakpoints.
If none of the above works consider refactoring your code that looks a bit messy.
Hey i have checked the code you wrote, it is working fine. Can you check if you have written similar to the code below in your cellForRowAtIndexPath.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *Identifier = #"Identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:Identifier];
}
UIButton *sched_button_a1 = [UIButton buttonWithType:UIButtonTypeCustom];
sched_button_a1.frame = CGRectMake(0, 0, 110, 52);
CGRect frame_a1 = sched_button_a1.frame;
[sched_button_a1 addTarget:self action:#selector(showAppointment:) forControlEvents:UIControlEventTouchUpInside];
[sched_button_a1 setTitle:#"Your Text" forState:UIControlStateNormal];
sched_button_a1.layer.backgroundColor = [UIColor redColor].CGColor;
[cell.contentView addSubview:sched_button_a1];
return cell;
}
I was not able to debug further as you have not kept your entire cellForRowAtIndexPath code. Hope this could help you to solve your problem
Since you are using a button type of UIButtonTypeCustom, you will need to set the attributes for UIControlStateHighlighted and UIControlStateSelected so that you achieve the effect you want for appearing to press the button.
You can change the title color or the background image for the highlighted and selected states using one of the following UIButton methods:
- (void)setTitleColor:(UIColor *)color forState:(UIControlState)state
- (void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state
As an additional note regarding the code in the cellForRowAtIndexPath, you shouldn't be getting the data from sql in the method it would be destructive to your table view performance, get all the data you need before and have them stored in object in an array and then in the cellForRowAtIndexPath method you would just update the values labels from the object for the row.

need Clarification on NSButton Creation and Usage

I have below code to create simple NSButton in a separate function
-(void)myFunction
{
NSButton *btn = [self createButton:#"Button_Name"];
if(some condition )
{
[btn setEditable:YES];
}
}
- (NSButton*)createButton:(NSString *)buttonName
{
NSButton *btn = [[NSButton alloc] initWithFrame:NSMakeRect(20, 0, 20, 20)];
[btn setButtonType:NSSwitchButton];
[btn setImagePosition:NSImageOnly];
[btn setTarget:self];
[btn setTitle: buttonName];
return btn;
}
In my same It is working fine.I am using this code in a Big project.Will It work normally or will cause some problem.Is this a correct way?
Few things I would like to bring in your notice:
You pass buttonName and buttonTitle but never uses it.
You create an object of type NSButton but your object name is against the convention, by reading btnCell someone will expect it to be NSButtonCell.
In the above code I cant see any reference to the newly created button and even you are not adding it to any view. (I hope in your real Big project you are not missing those.)

one button in each section of uiTableView objective-C

I have a uitableview and in my table I have different section and in each section different rows,I want to add one button in last row of each sections
I used sectionFooter, and here is my code, but I don't know why I have it just in my last section of table and also it's not appear with scroll.
Here is my code:
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 50;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
if(footerView == nil) {
footerView = [[UIView alloc] init];
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
// [button setBackgroundImage:image forState:UIControlStateNormal];
//the button should be as big as a table view cell
[button setFrame:CGRectMake(10, 3, 300, 44)];
//set title, font size and font color
[button setTitle:#"Report New Time" forState:UIControlStateNormal];
[button.titleLabel setFont:[UIFont boldSystemFontOfSize:20]];
[button setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
//set action of the button
[button addTarget:self action:#selector(removeAction:)
forControlEvents:UIControlEventTouchUpInside];
//add the button to the view
[footerView addSubview:button];
}
//return the view for the footer
return footerView;
}
what is wrong here, Would you please help me!
Thanks in advance!
You need to remove the if statement in your tableView:viewForFooterInSection: method. That's causing only one view to be created.
One UIView has to have only one superview. You have to create footerView for every section.
You are reusing the footerView for every section, partly by just keeping one footerView instance variable, partly by just creating it once. Every time UITableView asks you for a footer view for a section and it gets back the same view, that view is moved since it can't stay in all those places at the same time. The solution is to not use a single view.
Use an NSMutableDictionary to hold NSNumbers with the section number as key and the appropriate footer view as the value. Change the code to work with the section's "slot" in the dictionary instead of a single instance variable.

Objective C: UITable Method "didSelectRowAtIndexPath" does not work if label is added to cell

In my implementation, I had to add a custom label to the cell. However, I realize that by doing so, the cell area that is covered by the custom label will not react to the user's 'click' and hence will not trigger the method "didSelectRowAtIndexPath".
CustomOHAttributLabel *questionLabel = [[CustomOHAttributLabel alloc]initWithFrame:CGRectMake(10, (60-labelHeight)/2, 280, labelHeight)];
[cell.contentView addSubview:questionLabel];
Is there a way to allow the whole cell area to be responsive to the user's touch even after adding a Custom label to it?
Make a custom button and put that over the lavel and onClick call the same code, see this
CustomOHAttributLabel *questionLabel = [[CustomOHAttributLabel alloc]initWithFrame:CGRectMake(10, (60-labelHeight)/2, 280, labelHeight)];
UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom];
btn.frame=CGRectMake(10, (60-labelHeight)/2, 280, labelHeight);
[btn addTarget:self action:#selector(doSomeThing) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:questionLabel];
[cell.contentView addSubview:btn];
-(void)doSomeThing
{
//write code which you write in didSelectRowAtIndexPath method
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self doSomeThing];
}

UIButton created runtime in a loop, now I need a specific function depending on the button touched

I am creating some buttons and putting them inside a UIScrollView like this:
int i = 0;
while (i != numberOfButtons ) {
int updatetY = 160*i;
CGRect buttonFrame = CGRectMake(updatetY, 0, 160, 60);
UIButton *button = [[UIButton alloc] initWithFrame:buttonFrame];
UIImage *buttonImage = [UIImage imageNamed:#"bg.png"];
[button setBackgroundImage:buttonImage forState:UIControlStateNormal];
[button setTitle:[buttonsArray objectAtIndex:i] forState:UIControlStateNormal];
[button addTarget:self action:#selector(MYPROBLEM) forControlEvents:UIControlEventTouchUpInside];
[menuScrollView addSubview:button];
i++;
}
Now I need to build a method to capture which button is being touched, and run a specific bunch of code (see (MYPROBLEM).
Anybody knows what I can do to "trace" which button is being touched and then run a specific function?
something like:
-(void) buttonfunction
{
case ...
doThis
case...
doThat
}
thanks in advance.
You need to use the tag property of the uibutton control. It's a numeric id for the button. You can set a tag on the button based on the i variable in your loop, for instance:
button.tag=i;
Then in your button's action message, you would simply add the id of the button as a parameter and check its tag like so:
-(void) buttonFunction:(id)sender {
switch (sender.tag)
{
//code goes here
}
}
Hope this helps.