Adding definition to current selector of UIButton - iphone

I want to add a sound to every button sub-view in my UIView. I have so many of these buttons so I dont want to make a category or subclass of UIButton because in that case I have to change class name everywhere.
Is there anyway that I just loop [currentView subViews] and get button one by one, and add an action method.
Please keep in mind that buttons already have actions as well. So i am in search of some way to add definition to that action selectors.

try something like below...its not tested but should work...
for(UIButton *button in currentView.subViews) {
if ([button isKindOfClass:[UIButton class]]) {
[button addTarget:self
action:#selector(playSound)
forControlEvents:UIControlEventTouchUpInside];
}
}

Related

UIButton touchUpInside event not firing correctly

I have a tableview that contains a row with a custom cell that contains a UIButton. However, the button doesn't always fire the action. Here's my code:
submitButton = [[UIButton alloc] init];
[[submitButton layer] setBorderColor:[[UIColor whiteColor] CGColor]];
[submitButton setClipsToBounds: YES];
submitButton.backgroundColor = [UIColor grayColor];
[submitButton setTitle:#"Send" forState:UIControlStateNormal];
[self.contentView addSubview:submitButton];
[submitButton addTarget:self action:#selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
[submitButton release];
This is called in the custom cell's -(id)initWithStyle:
The buttonAction method looks like this:
-(void)buttonAction
{
NSLog(#"Button Clicked!");
}
It seems that the only way I can get the buttonAction to fire is if I press down on the button and release somewhere inside the cell's frame, but not inside the button itself. Why would that be?
*UPDATE*
Problem still exists, but I found that the more consistent way to get the button to fire is to click and drag to the left or right and then let go, as long as I let go within the bounds of the cell/row.
UPDATE #2
It looks like if I use iOS 6.0, it works as intended. But on 5.0 or 5.1 it does not.
Try assigning the same method call to TouchUpOutside as well - you should then see it work every time. TouchUpInside is only fired if you lift your finger while still within the bounds of the button.
Try [submitButton sizeToFit]. I'm wondering whether your button has any size (since I don't see you giving it any).
Also: Create your button with [UIButton buttonWithType: UIButtonTypeCustom] instead of alloc-init.

UIButton tags in iPhone

I have 2 button objects (UIButton *obtn,*ebtn), I have created 12 buttons(6 buttons with 6 tag values for obtn, 6 buttons with 6 tag values for ebtn)... I have a single btnClick: method for all those 12 buttons... when i click on a button of tag value 1... Iam getting the properties of selected button to another button by using sender... I want to get the properties of unselected button (Example obtn object with tag value 3) into another button How can i get it...?
My Direct Question is: How to assign the properties of a button with a tag value to another button when it is in unselected state...
It sounds like you want to be able to get a pointer to a button with a certain tag, and at the moment all you can do is get the button that has sent you the action.
The method you are looking for is viewWithTag:. This will get you a button (or any other view) with the tag you want. You pass this method to the superview of the button. So, in your action method (assuming all buttons are in the same superview):
UIView *superview = [sender superview];
UIButton *otherButton = [superview viewWithTag:3];
You then have sender, which is the button that was tapped, and otherButton, which is the button with tag 3. You can modify each one as you wish.
// Create textfield 5
btn_select_Country = [UIButton buttonWithType:UIButtonTypeCustom];
//btn_select_Client = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn_select_Country.frame = CGRectMake(BTN_X_CORD, 228, BTN_WIDTH, BTN_HEIGHT);
btn_select_Country.tag = 1;
// [btn_select_Client setTitle:#"Button One" forState:UIControlStateNormal];
[btn_select_Country addTarget:self action:#selector(countryListBtnTap:) forControlEvents:UIControlEventTouchUpInside];
btn_Image_Select_Country= [UIImage imageNamed:#"drop-down.png"];
[btn_select_Country setImage:btn_Image_Select_Country forState:UIControlStateNormal];
//btn_select_Client.tag=1205;
[scrollview addSubview:btn_select_Country];
- (IBAction)currencyListBtnTap:(id)sender;
{
button_Number = [sender tag];
[self allTextFeildResignFirstResponder];
}

Small UIButton on top of larger UIButton

I have a smaller UIButton which is on top of a larger UIButton.
The problem right now is that if I tap the smaller UIButton, it also will trigger the larger UIButton. The code I'm using to determine if the buttons were tapped is:
if(CGRectContainsPoint(button1.frame, location)) {
}
Is there a property of the buttons or some automated way to make the smaller button not effect the larger button?
I know I could alter the code above to say if its within button1's frame and not within button2, but is there another way to do it?
UIControl (which is the superclass of UIButton) passes itself as the only parameter to its target using the action selector. Make use it, it's there for exactly these cases!
[smallButton addTarget:self action:#selector(doStuff:) forControlEvents:UIControlEventTouchUpInside];
[bigButton addTarget:self action:#selector(doStuff:) forControlEvents:UIControlEventTouchUpInside];
// ...
- (void) doStuff:(UIButton *)btn
{
if (btn == smallButton)
{
// smaller button was clicked
}
else
{
// bigger button was clicked
}
}

How to remove background image to a button

I added 10 buttons to a view (example view name is "menuView"), now I want to remove the background image for 2nd, 3rd, 4th buttons. I wrote the code like this
for(id btn in [menuView subViews]){
[btn setBackgroundImage:nil forState:UIControlStateNormal];
}
The problem with this code is, it is removing all 10 button's backGroundimage, but I need to set nil for the 2nd, 3rd, and 4th buttons
If you create a tag for the buttons that you add, you can filter against them.
for(UIButton *btn in [menuView subViews]){
if (btn.tag == 2 || btn.tag == 3 || btn.tag == 4) {
[btn setBackgroundImage:nil forState:UIControlStateNormal];
}
}
Of course, you need to make sure that there are no other views in menuView that could share the same tag. So the choices are to make the tags large, unique values, or checking that they are actually UIButtons. I've edited this assuming that the only subviews of menuView are UIButtons. Enumerating over UIButtons won't cause compiler warnings about tag not being a property of NSObject.
UIButton is a subclass of UIControl which is a subclass of UIView. UIView has the tag property, so UIButton inherits this property. It's useful to look at the docs for a class that you are using, and continue up the hierarchy to see if there are properties or methods that are useful for what you need to do.
Just to expand on my comment.
Using an IBOutletCollection which you can point an array to many objects in the nib. You declare this as such (synthesizing in the implementation):
#property (nonatomic, retain) IBOutletCollection(UIButton) NSArray *threeButtons;
This says to IB that it's a collection of UIButton elements. In IB, you connect this to the three buttons you wish to remove the background image for, by control dragging from it to the buttons. Once this is done the array will contain those buttons you connected up and you can loop like so:
for (UIButton *button in self.threeButtons) {
[button setBackgroundImage:nil forState:UIControlStateNormal];
}
Again, the link to a more detailed explanation can be found at: http://bobmccune.com/2011/01/31/using-ios-4s-iboutletcollection
When creating the buttons, try using the "tag" property. Then, when you're setting the background to nil, you could check for btn.tag == 2,btn.tag == 3 or btn.tag == 4.
You could have assigned tags to the buttons from 1 to 10 when adding them to menu view. And now with the help of tags, we can decided what to do with buttons.
Firstly, are you placing the buttons using Interface Builder?
If so, I'd recommend placing numbered tags for each of the buttons and then you can use something like the following to find the appropriate buttons and remove the background image.
for(UIButton *buttonname in [yourView subViews]){
if (buttonname.tag == 2 || buttonname.tag == 3 || buttonname.tag == 4) {
[buttonname setBackgroundImage:nil forState:UIControlStateNormal];
}
}
If you're creating them programmatically and sequentially, I'd recommend placing the buttons in an array as they're made and just remove the background of the buttons using "objectAtIndex".

iPhone app: SDK 3.0 : Button Selected State: Can't get working!

Trying to do simple button functionality.
Button A. It has 3 states: default, highlighted, selected. Should UNSELECT when clicked again.
For the life of me, I can't even get a simple 3 state functionality established.
Highlight (on press) appears built in (goes to "stock" blue).
I"ve used Button Attributes to load in image for selected state...PLayed with Control/Content to click Highlight and Selected on and off, trying to find the right combo...
I thought it'd simply be selecting in dropdown the state I want to edit....and it would register my edits for that state...images loaded/ colors changed/ etc....
NO!!!!
What am I missing..?
What are you trying to do set the images or titles for the different states? For that you can just use methods such as
-(void)setImage:(UIImage *)image forState:(UIControlState)state;
OR
-(void)setTitle:(NSString *)title forState:(UIControlState)state;
is that what you are asking. May be i am misunderstanding your question because its not clear enough.
I couldn't find a straight answer about this anywhere. So I brewed my own solution that seems to work great.
Dont forget to wire up your buttons in IB you will need
to bind both
touch up inside to setButtonPressed
file owner to button ex. 1stButton
Psuedo Code
Clear all buttons selected
Set sender to selected
CODE
//Declare your buttons in .h
UIButton *1stButton;
UIButton *2ndButton;
UIButton *3rdButton;
#property(nonatomic, retain) IBOutlet UIButton *1stButton;
#property(nonatomic, retain) IBOutlet UIButton *2ndButton;
#property(nonatomic, retain) IBOutlet UIButton *3rdButton;
//In .m file - write 2 methods
-(void)clearButtons
{
[1stButton setSelected:FALSE];
[2ndButton setSelected:FALSE];
[3rdButton setSelected:FALSE];
}
//attach to touch up inside event in IB for each button
-(void) setButtonPressed:(UIButton *)sender
{
self.clearButtons;
[sender setSelected:TRUE];
[sender setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
}
You really should post some code (or an IB screenshot) as it's hard to fully parse what you are saying.
The default behavior of a UIButton is to show the Selected state on press, then revert back to the normal state. If you want it to "lock down" a press, you need to do something like this in the IBAction hooked to the UIButton:
BOOL pressed;
UIButton *button
- (IBAction) toggleButton:(id)sender
{
button.selected = ! pressed;
pressed = ! pressed;
}
AH! Well, not being a programmer, I was hoping for simple "stock" solution within Interface Builder.
To be clear of the "want/wish:
Button A-E. Each button should have 3 states: Default, highlight, selected.
Default: resting state.
Highlight: some treatment using interface builder features or import a graphic that will appear on Highlight. This state appears while button is being pressed.
Selected: when button A-E is released, it shows that it has been selected by displaying a new state, again by using tweaks within interface builder (font color, shadow) or import a graphic. When you click the SELECTED button again, it returns to Default state.
I guess I just thought it'd be "easy" because SDK 3.0 Interface Builder has dropdowns for the 3 states. I thought code would "magically" be assigned to the button allowing it to function as desired along with it's aesthetic shift.
I TOTALLY appreciate any and all feedback. I can pass along any coding advice to partner on this App.
Try this:
UIImage *img1 = [UIImage imageNamed:#"image1.png"];
UIImage *img2 = [UIImage imageNamed:#"image2.png"];
UIImage *img3 = [UIImage imageNamed:#"image3.png"];
[button setImage:img1 forState:UIControlStateNormal];
[button setImage:img2 forState:UIControlStateHighlighted];
[button setImage:img3 forState:UIControlStateSelected];
[button setImage:img2 forState:(UIControlStateHighlighted+UIControlStateSelected)];
[img1 release];
[img2 release];
[img3 release];
This is because the state variable is actually a bit flag.