Respond to touches on programmatically generated custom UIButtons inside UIScrollView - iphone

I have a UIScrollView full of custom UIButtons that are generated programmatically.
This code executes every iteration through the loop, typically 7 times.
[cardButton
addTarget:self
action:#selector(buttonPressed:)
forControlEvents:UIControlEventTouchUpInside];
[cardButton setTag:i + 100];
[self.scrollView addSubview:cardButton];
Elsewhere I have this function:
- (IBAction) buttonPressed:(id)sender
{
UIButton *button = (UIButton *)sender;
NSLog(#"%d", [button tag]);
}
How do I link the two? My button actually stores all the information I need from it inside its label so I really just need to detect when it is being tapped so I can respond.

You already linked two with this line
[cardButton
addTarget:self
action:#selector(buttonPressed:)
forControlEvents:UIControlEventTouchUpInside];
Sender is returning the instance of button which you pressed.so
- (IBAction) buttonPressed:(id)sender
{
UIButton *button = (UIButton *)sender;
NSLog(#"%d", [button tag]);
switch (button.tag) {
case 1:
//Action for button with tag 1
break;
case 2:
//Action for button with tag 2
break;
default:
break;
}
}

Related

How to save a reference to a control added programmatically?

I added 3 buttons programmatically to my view, then I added the buttons to an array so that I can access them at a later time:
for (i = 0; i < 3; i++)
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[view addSubview:button];
[_buttons addObject:button];
}
If I reference the button in my array and change the image of the button, it does not change the button on screen.
UIButton* button = [_buttons objectAtIndex: 0];
[button setImage:thumb forState:UIControlStateNormal];
I've found a way to change the image of the button by looping through all the subviews in my view, but is there a better way?
for (UIView* subView in ((UIView*)[self.view.subviews objectAtIndex:0]).subviews){
if ([subView isKindOfClass:[UIButton class]]){
UIButton *button = (UIButton*)subView;
if (button.tag == self.selected){
[button setImage:thumb forState:UIControlStateNormal];
}
}
}
A common reason for this is that your array has not been initialized. When this happens, Objective C does not complain or throw excetions: instead, it behaves as if the calls to add elements never happened. It also returns nil when you try getting items back.
Add this line to your viewDidLoad method:
_buttons = [NSMutableArray array];
This should solve the problem.
Possible this could help on a click event:
-(void)clickEvent:(id)sender
{
[sender setImage:thumb forState:UIControlStateNormal];
}
If this is how you are picking up the event.
When you do addSubview, view retains subview you are adding. Also addObject retains it. Hence both are different ojbects. Changing properties of object in array will not affect object retained by view.
You can avoid loop by using tags. While adding buttons on view set unique tags to them. And when you want to access them, get it using tag directly.
//set tags for buttons
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setTag:999];
[view addSubview:button];
//access using tag
UIButton *button = (UIButton*)[view viewWithTag:999];
[button setImage:thumb forState:UIControlStateNormal];
Add a tag to the button after creating it. And later use that tag to get that button.
for (i = 0; i < 3; i++)
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.tag = i+1;
[view addSubview:button];
[_buttons addObject:button];
}
Then you can access it like:
UIButton *button1 = (UIButton *)[self.view viewWithTag:1];
UIButton *button2 = (UIButton *)[self.view viewWithTag:2];
UIButton *button3 = (UIButton *)[self.view viewWithTag:3];
While adding UIControl programatically to use reference later add tag to it which should be different like:
yourBtn.tag = 111;
Now get reference of UIButton like this:
UIButton *button = (UIButton*)[yourViewWhereYouAdded viewWithTag:111];

iPhone . button image not switching

I have implemented a radio button on one of my apps, exactly like this solution:
http://www.developers-life.com/radio-buttons-in-iphone-application.html
but my checkboxButton method is like this:
- (IBAction)checkboxButton:(UIButton *)button{
for (UIButton *but in self.arrayButtons) {
if (but == button)
[but setSelected:YES];
else
[but setSelected:NO];
}
}
I have two buttons belonging to the same radio button group. When I select one of the buttons its image toggles to the switched one. Perfect. The problem is that when I select the other one it will not select to selected state and the first one that is being displayed as selected continues to be displayed as selected.
any clues?
for (UIButton *but in [Your_View subviews]) {
if ([but isKindOfClass:[UIButton class]] && ![but isEqual:button]) {
[but setSelected:NO];
}
}
if (!button.selected) {
button.selected = !button.selected;
}
why are you using so much complicated just use below to make selected..
- (IBAction)checkboxButton:(UIButton *)button
{
button.selected = !button.selected;
}
and make sure your images for button are set in the xib for each state as required.
In order to achieve the desired functionality, you will have to do selection of buttons in the next run loop.
So, call another method from "checkboxButton:".
Do something like,
- (IBAction)checkboxButton:(UIButton *)button
{
[self performSelector:#selector(highlighButton:) withObject:button afterDelay:0.0];
}
Where "highlightButton:" is defined as:
-(void) highlighButton:(UIButton*)aButton
{
[aButton setHighlighted:YES];
for (UIButton* button in self.arrayButtons) {
if (button != aButton) {
[button setHighlighted:NO];
}
}
}
I just made a few slight tweaks, and I just tested this and it works.
viewDidLoad: //making sure all buttons have the same selector assigned
[button1 addTarget:self action:#selector(checkboxButton:) forControlEvents:UIControlEventTouchUpInside];
[button2 addTarget:self action:#selector(checkboxButton:) forControlEvents:UIControlEventTouchUpInside];
[button3 addTarget:self action:#selector(checkboxButton:) forControlEvents:UIControlEventTouchUpInside];
Then just slightly modifying the loop to scan for button subviews instead of objects in an arbitrary array (should be more accurate)
- (IBAction)checkboxButton:(UIButton *)button{
for (UIButton *but in self.view.subviews) {//Change "self.view" to what ever view you are adding these subviews to.
if (but == button){
[but setSelected:YES];
}else{
[but setSelected:NO];
}
}
}
Keep in mind the selected state image/text that you are assigning will not appear until the button is released. When the button is pressed before it is released it is in its highlighted state. This is just a note so you can set this up accordingly.
After trying all solutions given here and have all failed, I tried a new approached and it worked perfectly.
The solution was to change this
- (IBAction)checkboxButton:(UIButton *)button{
for (UIButton *but in self.arrayButtons) {
if (but == button)
[but setSelected:YES];
else
[but setSelected:NO];
}
}
to this
- (IBAction)checkboxButton:(UIButton *)button{
for (UIButton *but in self.arrayButtons) {
if (but == button)
[but setImage:selectedImage forState:UIControlStateNormal];
else
[but setImage:normalImage forState:UIControlStateNormal];
}
}
apparently, changing the state of the button will not change its image. At least did not work for me.

How to create individual action for each button in icarousel?

I've created an app that shows 8 buttons in coverflow using icarousel.i have to assign different action for each button.Here is my piece of code for viewcontroller.m file..
- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel
{
return NUMBER_OF_ITEMS;
}
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
UIImage *buttonImage=[NSArray arrayWithObjects:[UIImage imageNamed:#"Cover_0.png"],
[UIImage imageNamed:#"Cover_1.png"],
[UIImage imageNamed:#"Cover_2.png"],
[UIImage imageNamed:#"Cover_3.png"],
[UIImage imageNamed:#"Cover_4.png"],
[UIImage imageNamed:#"Cover_5.png"],
[UIImage imageNamed:#"Cover_6.png"],
[UIImage imageNamed:#"Cover_7.png"],nil];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0, 0, 200.0f, 200.0f);
[button setImage:(UIImage*)[buttonImage objectAtIndex:index] forState:UIControlStateNormal];
[button addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
return button;
}
- (void)buttonTapped:(UIButton *)sender
{
}
Here i've got stuck...now i want to assign different action for each button.but if i declare an action under buttonTapped it gets assigned for all the buttons..Can anyone help?...
additional to my previous question i've added other two buttons and two event to that buttons in xib file and defined method in my .m file...But if i run that on simulator its just displayed as image and cant interact with that button...Any idea pls...
You can ask the carousel which button was pressed like this:
- (void)buttonTapped:(UIButton *)sender
{
NSInteger index = [carousel indexOfItemViewOrSubview:sender];
switch(index) {
case 0:
//do action number 1
break;
case 1:
//do action number 2
break;
etc....
}
}
just you call base on the button tag value.
get button tag value
- (void)buttonTapped:(UIButton *)sender
{
uibutton *btn=(uibutton *) sender;
nslog(#"button tag== %d",btn.tag);
}

How can i maintain the selected state in button in iPhone

I have created scroll view and sets the buttons are in the scroll view. The Buttons are scrolling horizontally and it works fine. If i clicked the button, i set background image as "Selected State" in button. My problem is how can i changed the selected state in different button, when clicking it and how can i deselected the "selected state" button when clicking the another button.
I have three buttons in the scroll view,
-(IBAction) Button1 : (id) sender
{
// btn1.selected = YES;
[btn1 setImage:[UIImage imageNamed:#"first.png"] forState:UIControlStateSelected];
}
-(IBAction) Button2 : (id) sender
{
// btn2.selected = YES;
[btn2 setImage:[UIImage imageNamed:#"second.png"] forState:UIControlStateSelected];
}
-(IBAction) Button3 : (id) sender
{
// btn3.selected = YES;
[btn3 setImage:[UIImage imageNamed:#"three.png"] forState:UIControlStateSelected];
}
see the below image,(Health, Entertainment and Money Watch are the three buttons)
Image http://www.freeimagehosting.net/uploads/6b3daab12f.png
and
Img http://www.freeimagehosting.net/uploads/b6e0f234dc.png
Note:(Like, Tabbar and Segmented control)
On clicking first button and sets background image in selected state and clicking the second button, then first buttons are to be deselected. So how can i maintain the selected state, till another button is clicked.
Thanks in Advance.
I solved this task in the following way:
init method:
Create number of buttons with defined images for normal and selected state.
Assign tag for each button (for example, for i'th button tag is 1000+i).
Assign IBAction for each button.
action method:
Remove selection from previously selected button (search it by it's tag with [view viewWithTag:] method)
Select sender.
Save sender's tag.
Here's the code:
- (void)init {
....INITIALIZE SCROLLVIEW HERE.....
for ( int i = 0; i < 10; i++ ) {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setFrame:.....];
[btn setImage:_IMAGE_ forState:UIControlStateNormal];
[btn setImage:_IMAGE2_ forState:UIControlStateSelected];
[btn setTag:i + 1000];
[btn addTarget:self action:#selector(setSelectedButton:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:btn];
}
}
- (IBAction)setSelectedButton:(id)sender {
[self setSelectedButtonByIndex:((UIButton *)sender).tag - 1000];
}
- (void)setSelectedButtonByIndex:(NSInteger)index {
if ( selectedElemId >= 0 ) {
UIButton *btn = (UIButton *)[self viewWithTag:selectedElemId + 1000];
[btn setSelected:NO];
}
UIButton *btn = (UIButton *)[self viewWithTag:index + 1000];
[btn setSelected:YES];
selectedElemId = btn.tag - 1000;
}

UIButton : managing dynamic creation and touch events

I'm currently dynamically creating UIButton objects in my view.
I have an NSMutableArray containing information about them (id - label).
I then create my view objects by doing a for iteration on my MutableArray.
I'm trying to use this code on my buttons to catch touche events :
[myButton addTarget:self action:#selector(selectedButton:) forControlEvents:UIControlEventTouchUpInside];
My selectedButton method is called with success, but I don't have any idea on knowing with button were touched.
I tried to do this :
-(void)selectedButton:(id)sender {...}
But don't know what to do with the sender object.
Thanks in advance for your help !
At the top of your .m file, put something like this:
enum {
kButtonOne,
kButtonTwo
};
When you're creating your buttons, do this
myButton.tag = kButtonOne;
Then in your selected button method, do this:
-(void)selectedButton:(id)sender {
switch (sender.tag) {
case kButtonOne:
// do something here
break;
case kButtonTwo:
// do something else here
break;
}
}
Set mybutton.tag to something, and then check for that tag in selectedButton:sender.
-(void)viewDidLoad{
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(80.0, 210.0, 40.0, 30.0);
button.tag=1;
[button addTarget:self
action:#selector(aMethod:)
forControlEvents:UIControlEventTouchDown];
[button setTitle:#"raaz" forState:UIControlStateNormal];
[self.view addSubview:button];
}
-(IBAction)aMethod:(id)sender{
UIButton *btn=(UIButton *)sender;
NSLog(#"I have currently Pressed button=%d",btn.tag);
}