Custom TableView issue - iphone

I have a custom header view in my iphone app. and it have a custom button over that.
But that custom button action is not fire but header tap event is fired which is in custom class .Please help me .How to fire action on button in header view.
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
NSNumber *num=[NSNumber numberWithInt:section];
UIView * customView = [[[UIView alloc] initWithFrame:CGRectMake(0,0,320,50)]autorelease];
customView.tag = section;
[customView setUserInteractionEnabled:YES];
customView.backgroundColor = [UIColor blackColor];
UIButton *button=[UIButton buttonWithType:UIButtonTypeCustom];
button.frame=CGRectMake(260, 7, 25, 25);
button.tag=section;
[button addTarget:self action:#selector(expandCollapsing:) forControlEvents:UIControlEventTouchUpInside];
[button setImage:[UIImage imageNamed:#"add.png"] forState:UIControlEventTouchUpInside];
[button setSelected:YES];
}

You can implement your own callback method to do this.
What i did is I added a TapGesture to the customView. When the event is fired i used a callback method to pass the control to the viewController where my tableView is implemeted
What you can do While loading the header you can assign the tag value to the customView
customHeader.tag = 1;
and you can implement the call back method in your viewController.
In CustomheaderView
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(checkBoxEventHandler:)];
[recognizer setNumberOfTapsRequired:1];
[recognizer setNumberOfTouchesRequired:1];
[self setGestureRecognizers:[NSArray arrayWithObject:recognizer]];
-(IBAction)checkBoxEventHandler:(id)sender
{
if ([self.delegate respondsToSelector:#selector(selectedHeader: atIndex:)])
{
[self.delegate selectedHeader:self atIndex:self.tag];
}
}
In your viewController.m
-(void)selectedHeader:(myCustomHeader *)header atIndex:(int)index
{
//header -> will give you the same instance you created in your viewController while loading this custom header view
// So you can check the tag like this
if(header.tag == 1)
{
//Do Stuff here
}
// index -> we are passing headerViews tag as index ie header.tag is equal to index
// So checking the tag like this is the proper way
if(index == 1)
{
//Do Stuff here
}
}

Just paste this code will solve your problem :
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
UIButton *button=[UIButton buttonWithType:UIButtonTypeCustom];
button.frame=CGRectMake(50.0, 0.0, 25, 25);
[button setImage:[UIImage imageNamed:#"add.png"] forState:UIControlStateNormal];
button.tag=section;
[button addTarget:self action:#selector(expandCollapsing:) forControlEvents:UIControlEventTouchUpInside];
[button setSelected:YES];
return button;
}
-(void)expandCollapsing:(id)sender {
UIButton *btn=(UIButton*)sender;
NSLog(#"Tag:%d",[btn tag]);
}

Related

Programmatically added button getting crash in storyboard

I am adding a button in UIScrollView in StoryBoard
Below is the code i am using.
-(void)addScrollView
{
for(int i=0;i<[array count];i++)
{
UIScrollView *subScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 400, SUBSCROLLVIEW_WIDTH, SUBSCROLLVIEW_HEIGHT)];
UITextView *txtVwDetail = [[UITextView alloc] initWithFrame:CGRectMake(342, 0, TEXTVIEW_WIDTH, TEXTVIEW_HEIGHT)];
txtVwDetail.text = SAMPLE_STRING;
[self addSubScrollView:subScrollView];
[self.view addSubview:subScrollView];
[self.view addSubview:txtVwDetail];
}
}
-(void)addSubScrollView:(UIScrollView *)aSubScrollView
{
for(int i=0;i<[array count];i++)
{
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
aButton.frame = CGRectMake(intBtnX, (aSubScrollView.frame.size.height - 80)/2, 50, 80);
[aButton setImage:[UIImage imageNamed:[self.items objectAtIndex:i]] forState:UIControlStateNormal];
**[aButton addTarget:self action:#selector(btnSubImageClicked) forControlEvents:UIControlEventTouchUpInside];**
aSubScrollView.contentSize = CGSizeMake(intScrollViewWidth, aSubScrollView.frame.size.height);
[aSubScrollView addSubview:aButton];
}
}
In addSubScrollView method I have added Button and its click event which is getting crashed.
-(void)btnSubImageClicked
{
NSLog(#"btnSubImageClicked");
}
I am having scenario as
MyMainViewController is the sourceViewController for my created customSegue which is the UIStoryboardSegue class
MyMainViewController having a UIView as PlaceHolderView in which I am adding MydestinationViewContoller's View which is this Scrollview
-(void)perform
{
BrowseScreenVC *srcObj = (BrowseScreenVC *)[self sourceViewController];
UIViewController *dstObj = (UIViewController *)[self destinationViewController];
for(UIView *vw in srcObj.viewPlaceHolder.subviews)
{
[vw removeFromSuperview];
}
NSLog(#"dest : %#",dstObj.view);
NSLog(#"destobj :%#",dstObj);
srcObj.currentViewController = dstObj;
[srcObj.viewPlaceHolder addSubview:[dstObj.view retain]];
}
UPDATE
With answer I also have to change the line
srcObj.currentViewController = dstObj;
to
srcObj.addChildViewController = dstObj;
to make it working
you have to add target as follow:
[aButton addTarget:self action:#selector(btnSubImageClicked:) forControlEvents:UIControlEventTouchUpInside];
#selector(), within these braces you have to provide the method that you want to perform. the ":" represents that the method has some argument. In this case the argument would be the button itself that is calling the method.
You have to implement your method then its signature would look like this
- (void)btnSubImageClicked:(id)sender{
// sender would be the button that is calling the method. you can use this object according to your requirements if you want.
// your code
}
if you want to call this method from somewhere else as well you can call it by passing sender argument nil. e.g [self btnSubImageClicked:nil];
Your action needs to accept an (id) sender argument, even if you are not using it:
-(void)btnSubImageClicked:(id) sender
{
NSLog(#"btnSubImageClicked");
}
In the addSubScrollView:
[aButton addTarget:self action:#selector(btnSubImageClicked:) forControlEvents:UIControlEventTouchUpInside];
Button target should like
-(void) btnSubImageClicked:(id)sender{}
try this.
Updated:-
Please correct your code,change this line
[aButton addTarget:self action:#selector(btnSubImageClicked:) forControlEvents:UIControlEventTouchUpInside];
Now working i checked.
Instead of
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
write this,
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
and for better practice always write this,
-(void) btnSubImageClicked:(id)sender{}

Add a Button to a TableView Cell:

I have a UI tableView and I am trying to create a button like the one used in the Safari Settings to Clear History:
The code I have tried doesnt really work and I'm sure there is a better way:
case(2):
// cell = [[[ButtonLikeCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
if (indexPath.row == 0)
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:cell.bounds];
[button addTarget:self action:#selector(clearButtonClick) forControlEvents:UIControlEventTouchUpInside];
[button setBackgroundColor:[UIColor purpleColor]];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button setTitle:#"Clear Data" forState:UIControlStateNormal];
cell.accessoryView = nil;
cell.clipsToBounds=YES;
[cell.contentView addSubview:button];
}
break;
}
}
return(cell);
}
A subclass on the tableview cell is overkill for this, basically all you need to do is set the text alignment of the textLabel to center
case(2):
if (indexPath.row == 0)
{
cell.textLabel.textAlignment = UITextAlignmentCenter;
}
break;
no need to use an actual UIButton.
the only difference between does rows and "normal" rows is the position of the label.
subclass UITableViewCell and override -laysubviews to center the label and you're done, like so:
#interface ButtonLikeCell : UITableViewCell
#end
#implementation ButtonLikeCell
-(void)layoutSubviews
{
self.titleLabel.center = self.center;
}
#end
this will reposition the label of the cell and make it look similar to what you're looking for.

Putting a button in table footer view

I am creating a custom button and putting it in my table's footer view but the button is going way out from the right corner.
What is wrong here!?!
Here is my code and output image:
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
[aButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[aButton setTitleColor:[UIColor colorWithWhite:0.0 alpha:0.56] forState:UIControlStateDisabled];
[aButton setBackgroundImage:[[UIImage imageNamed:#"test.png"] stretchableImageWithLeftCapWidth:kButtonSliceWidth topCapHeight:0] forState:UIControlStateNormal];
[aButton setTitle:#"Click me" forState:UIControlStateNormal];
[aButton.titleLabel setFont:[UIFont boldSystemFontOfSize:kFontSize14]];
[aButton setFrame:CGRectMake(10.0, 15.0, 300.0, 44.0)];
[self.tableView setTableFooterView:aButton];
I added the button in the UIView and then set the tableFooterView to this UIView object and it worked. We cannot directly put UIButton as tableFooterView.
Try doing like this. Set IBOutlet UIView *footerView; and synthesize it. Add it as a subview using the method-
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
if(footerView == nil) {
//allocate the view if it doesn't exist yet
footerView = [[UIView alloc] init];
//create the button
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setFrame:CGRectMake(10, 3, 300, 44)];
//set title, font size and font color
[button setTitle:#"Click Me" forState:UIControlStateNormal];
[button.titleLabel setFont:[UIFont boldSystemFontOfSize:18]];
//set action of the button
[button addTarget:self action:#selector(clickPressed:)
forControlEvents:UIControlEventTouchUpInside];
//add the button to the view
[footerView addSubview:button];
}
//return the view for the footer
return footerView;
}
One important addition to Legolas' fine answer: You'll need to implement the tableView delegate method:
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
foot 50;
}
This was driving me nuts because the button (or, in my case, buttons) were not responding to the touch event. Adding the delegate method made it all better. :-)

How to get button.tag via longPressGestureRecognizer?

I'm dynamically adding image buttons to some scrollview. They all point at one longPressHandler. Now, how do I get which button was pressed? The [sender tag] gives me the tag of longGestureRecognizer that I added to button and I can't manually set that tag.
for (...) {
UIButton *button = [[UIButton alloc] init];
button.tag = w + h * 3;
[button addTarget:self action:#selector(imageButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
UILongPressGestureRecognizer *gest = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(imageButtonLongPress:)];
gest.minimumPressDuration = 1;
gest.delegate = self;
[button addGestureRecognizer:gest];
[gest release];
[scrollView addSubview:button];
[button release];
}
- (void) imageButtonLongPress:(id)sender {
// how to get button tag here?
}
There is a view property in the UIGestureRecognizer which returns the view that recognizer is attached to. I think that is your best bet.
- (void) imageButtonLongPress:(id)sender {
UIGestureRecognizer *recognizer = (UIGestureRecognizer*) sender;
int tag = recognizer.view.tag;
}
In your action you have to type cast your sender in gesture and then type cast its view to a button then get button's tag as -
UILongPressGestureRecognizer *gest = (UILongPressGestureRecognizer *)sender;
UIButton *button = (UIButton*)[gest view];
NSLog(#"%d",[button tag]);

change button state in cellForRowAtIndexPath

this is driving me MAD now.. I have a UItableview. Based on an NSMutableArray, I populate it.
I set up in reuseTableViewCellWithIdentifier with the following
cellRectangle = CGRectMake((ARROW_OFFSET + 5), (ROW_HEIGHT - LABEL_HEIGHT) / 2.0, ARROW_WIDTH, LABEL_HEIGHT);
UIButton *tmpButton = [[UIButton alloc] initWithFrame:cellRectangle];
[tmpButton initWithFrame:cellRectangle];
[tmpButton setImage:[UIImage imageNamed:#"icon_edit.png"] forState:UIControlStateNormal];
[tmpButton setImage:[UIImage imageNamed:#"icon_no.png"] forState:UIControlStateDisabled];
[tmpButton addTarget:self action:#selector(editSelectedRow:) forControlEvents:UIControlEventTouchUpInside];
tmpButton.tag = ARROW_TAG;
[cell.contentView addSubview: tmpButton];
[tmpButton release];
then in cellForRowAtIndexPath I have the following lines of code
UIButton *button = (UIButton *)[cell viewWithTag:ARROW_TAG];
[button setTag:indexPath.row];
if (counterHasStarted == 1) {
NSLog(#"yes");
button.enabled = NO;
} else {
button.enabled = YES;
}
the button shows nicely, but for some reason when the counterHasStarted variable (which is an int is set, it doesn't change! I can change UILabels based on the above code (checking if counterHasChanged is 1 or 0).
Any ideas what's going on??
-cellForRowAtIndexPath: will only get called when the table view needs a new UITableViewCell because the user scrolled.
I guess you're changing counterHasStarted and expect the button enabled state to change? You could reload the data when you change counterHasStarted ([yourTableView reloadData]). Then the table view will call -cellForRowAtIndexPath: for all the cells that are currently visible, and you can enable or disable the buttons as needed.