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.
Related
I currently have 3 objects called MenuButton that's a child of UIButton. These are defined in a row as shown in the image.
I've defined the highlight states in my MenuButton -didUpdateFocusInContext:withAnimationCoordinator method:
- (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context
withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator
{
if (context.nextFocusedView == self)
{
[self setTitleColor:[UIColor whiteColor]
forState:UIControlStateNormal];
}
else if (context.previouslyFocusedView == self)
{
[self setTitleColor:[UIColor colorWithRed:25.0/255.0
green:23.0/255.0
blue:16.0/255.0
alpha:1.0]
forState:UIControlStateNormal];
}
}
I've also set canBecomeFocused in the MenuButton object via:
- (BOOL)canBecomeFocused
{
return YES;
}
I've set my initial focus button using:
[_camerasButton setNeedsFocusUpdate]
When I swipe right on the Simulator remote, I'm not able to get it to focus on Deliveries.
Can someone please explain how I can use UIFocusGuide to implement this correctly in Objective-C?
UPDATE 1
Based on JustinVoss' suggestion on the first comment, I set breakpoint and did a _whyIsThisViewNotFocusable on the debug console. Received this hint:
(lldb) po [(UIView*)0x7ff68054f7c0 _whyIsThisViewNotFocusable]
ISSUE: This view may not be focusable because other views or focus guides are occluding it.
I'm defining my MenuButton frames as shown:
MenuButton *deliveriesButton = [MenuButton buttonWithType:UIButtonTypeCustom];
[deliveriesButton setTitle:#"Deliveries" forState:UIControlStateNormal];
[deliveriesButton setTitleColor:[UIColor colorWithRed:25.0/255.0
green:23.0/255.0
blue:16.0/255.0
alpha:1.0]
forState:UIControlStateNormal];
[deliveriesButton.titleLabel setFont:[Constants lightFontOfSize:39]];
[deliveriesButton sizeToFit];
deliveriesButton.center = CGPointMake(viewWidth/2,
menuBarHeight / 2);
[self.view addSubview:deliveriesButton];
_deliveriesButton = deliveriesButton;
Using the solution referenced by Justin Voss in the comments above, I went through the UIViews in my UIViewController and set:
view.userInteractionEnabled = NO;
on any view that I did not need to have a selection on (including background UIImageView objects). This resolved the problem.
Hope this helps someone else
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.
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.
I have 2 buttons in the header of tableView1. I want it so that when people click either button, two things happen:
tableView1 disappears
tableView2 shows up
or
tableView1 shows up
tableView2 disappears
how can I do that using IOS?
I tried doing the following:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == 0)
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage: [UIImage imageNamed:#"tableheader_01.png"]forState:UIControlStateNormal];
button.frame = CGRectMake(0, 0, 159, 57);
button.tag = 7;
[button addTarget:self action:#selector(hideTable:) forControlEvents:UIControlEventTouchUpInside];
UIButton *button2 = [UIButton buttonWithType:UIButtonTypeCustom];
[button2 setImage: [UIImage imageNamed:#"tableheader_02.png"]forState:UIControlStateNormal];
button2.frame = CGRectMake(159, 0, 161, 57);
button2.tag = 7;
[button2 addTarget:self action:#selector(hideTable:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview: button];
[cell.contentView addSubview: button2];
Where the hideTable has the following code:
-(IBAction) hideTable : (id) sender;
{
NSLog(#"test");
[self.myTableView1 setHidden:YES];
[self.myTableView2 setHidden:NO];
}
but this does not work.
There are so many possibilities to implement such UI.
1.Either you can keep both buttons outside or above both tables.So that if you click on button1 you hide first table & show second & when click on second hide second table & show first table.
OR
2.In first table add two button at first row as you did.When you click on button1 then instead of hiding first table return 1 for table1 data source in numberofrows method & reload table1, so that buttons will be there & then show second table below first table.When user click on second button then hide second table & return new data source for first table & reload table1.
OR
3.Use one table for both data source.At first row there will be two buttons.On clicking on them reload table accordingly.
You could use a single table view and just change the data source when a button is clicked, then reload the tableview.
You can set the self.myTableView1.datasource = nil and when you need to use it, you can set self.myTableView1.datasource = self and [self.myTableView1 reloaddata]
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];
}