Group several UIButtons into a single button - ios

Is it possible to wrap several controls/buttons into a single button where all buttons react (highlight/unhighlight) to presses on any of the elements, and all share the same action?
I'd like to have multiple "parts" (mainly labels and icons) of a button that I can control the layout for individually, but I want them to all behave as a single button and highlight all of the parts when tapped.
Perhaps I could track the pressed state of each button and make all the other components have the same state?

You can drag the little dot to multiple buttons in your view and all those buttons will run the same IBAction code.
If you want to differentiate between them, you can use tags in interface builder and then call upon those tags with [sender tag]
So your IBAction could look a little like this:
- (IBAction)button_myButtonWasPressed:(id)sender {
if ([sender tag] == 0) {
// This will run for button tag 0
}
if ([sender tag] == 1) {
// This will run for button tag 1
}
}

Related

iOS, stopping a second button being tapped in an outlet collection, when two are tapped?

I have this weird bug, I wouldn't expect users to do this, but as it's a kids app, therefore I need my app to perform well and not do something unexpected. Which it does.
I have an outlet collection for several buttons and an IBAction.
It's possible for someone, using two fingers, to tap two buttons at once.
I've tried this, however it still runs for both.
Can anyone suggest how I work round this problem ?
- (IBAction)btnBtnNum:(id)sender {
for( UIButton *button in self.buttonCollection )
{
if( sender != button )
{
[sender setEnabled:NO];
}
}
If it doesn't break anything else, you should look at the property multipleTouchEnabled.

how to create tabs that expands when selected in iOS

I want to create a tableView or tabs that expands when user selects them. This is very commonly used in webpages using jquery.
you can check http://jqueryui.com/accordion/ It does exactly what i want to do in my ipad app. with horizontal tabs too http://jqueryui.com/tabs/
Can anyone tell me how to achieve this in my iPad app ? Or any pointers would be appreciated.
TIA
Sam
1.Use UITableView for first type of tab.
a) Use Header and Cell View in your desired format.
b) Hide and unhide cell view with some animation.
2.Use UISegementedControl for second type of tab.
a) Use function addTarget :
[self.mySegmentedControl addTarget:self action:#selector(segmentChanged) forControlEvents:UIControlEventValueChanged];
b) Implement segmentChanged :
- (void) segmentChanged:(UISegmentedControl *)paramSender{
//check if its the same control that triggered the change event
if ([paramSender isEqual:self.mySegmentedControl]){
//get index position for the selected control
NSInteger selectedIndex = [paramSender selectedSegmentIndex];
if (selectedIndex == 1 ) { // do required } and so on....
}
}
The best possible way is using the headerview to show the Master row and the tableview cells for showing the Details row.Write a touch event for the headerview and set it with the showing and hiding the cells ,with neat row animation.You need to keep the status of the opened and closed state of cell with an array of bools repesenting the no of masterview.

How to set the UIButton state to be highlighted after pressing it

I have a typical requirement wherein I need to keep a button in highlighted state after pressing it. I need to perform a task which should work only when a button is in highlighted state. Actually I am setting a button state to highlighted programatically.
[sender setHighlighted:YES];
And once the button is in highlighted state i need to perform another action.
- (IBAction)changeState: (UIButton*)sender
{
if (sender.highlighted == YES)
{
[self performSomeAtion:sender];
}
}
But, to my horror, whenever I press any button, the above condition is becoming true and the action is being performed repeatedly. Is there any way in which i can keep a UIButton's state to be highlighted after pressing it?
EDIT - Actually I need to perform 3 different actions for 3 different states of the button. I am already making use of selected state and normal state. Now, I need to make use of the highlighted state.
[sender setSelected:YES];
or you can simulate this effect with two image for your UIButton (notselectedimage.png and selectedimage.png), then keep track button state with a BOOL variable like BOOL buttonCurrentStatus;. Then in .h file:
BOOL buttonCurrentStatus;
and in .m file
// connect this method with Touchupinside function
- (IBAction)changeState:(UIButton*)sender
{
/* if we have multiple buttons, then we can
differentiate them by tag value of button.*/
// But note that you have to set the tag value before use this method.
if([sender tag] == yourButtontag){
if (buttonCurrentStatus == NO)
{
buttonCurrentStatus = YES;
[butt setImage: [UIImage imageNamed:#"selectedImage.png"] forState:UIControlStateNormal];
//[self performSomeAction:sender];
}
else
{
buttonCurrentStatus = NO;
[butt setImage:[UIImage imageNamed:#"notSelectedImage.png"] forState:UIControlStateNormal];
//[self performSomeAction:sender];
}
}
}
- (void)mybutton:(id)sender
{
UIButton *button = (UIButton *)sender;
button.selected = ![button isSelected]; // Important line
if (button.selected)
{
NSLog(#"Selected");
NSLog(#"%i",button.tag);
}
else
{
NSLog(#"Un Selected");
NSLog(#"%i",button.tag);
}
}
The highlighted state is used to highlight the button while it is being touched. A touch down event in the button highlights it. You should use the "selected" state instead.
If what you want to do is perform an action after the button is pressed, don't attach your method to the state change event, attach your method to the TouchUpInside event.
I just find a way, so I share it, just in case...
I kept my UIButton and set one image for each state (so you could go up to a 4 states button).
I set the UserInteractionEnabled to NO -> This button won't receive any touch.
The purpose of this first button is to show a state
I create a second custom UIButton with the same frame than the first one. For this one, none image will be set for the state (it's a fully transparent button). The purpose of this button is to catch the touch event. So I added a target to this button on the TouchUpInside event. And then when the event is fired, I change the state of the first button to Disabled, Highlighted, Selected, or none of these state (= Default state).
Everything is working like a charm!
The way you describe it, you'd be better off subclassing UIView to create your own three-state button.
Actually, you should even implement your own multistate buttonView, and manage the state it's in internally via an array of PNG for the looks and an array of states to know how many times it's been pressed.
Use [sender setSelected: YES];, I think it will be useful to you.
UIButton *btn_tmp=sender;
if(!(btn_tmp.selected))
{
[btn_temp setHighlighted:YES];
}
For iOS 7 only: you should consider setting the image renderMode to UIImageRenderingModeAlwaysTemplate. You can then use the tintColor to represent various states.
see How to apply a tintColor to a UIImage?
and
see Tint a UIView with all its subviews
The solution is tricky but it's possible.
The problem is that you tried to change the highlighted status in the button action method, which I suppose makes a clean up or check process at the end of the action and switch the highlighted status. When you try to debug it you get the highlighted = 1 but it will change at the end.
Strange but your "3 statuses button" is sometimes useful, when you'd like to keep a button in "highlighted" mode like the "selected" mode to get different action depending on the 3 statuses.
The only problem that you couldn't analyze this or switch it to highlighted mode in the button action method as this will switch to highlighted mode immediately as the user push it AND switch it back at the end.
The solution is using a dispatch.
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[theButton setHighlighted:YES];
});
This will do the trick and you could use the 3 statuses.
According to apple, UIButton has a property of imageView:
Although this property is read-only, its own properties are read/write. Use these properties to configure the appearance and behavior of the button’s view
This means that you can set in the IB (in the storyboard) a picture for this button and set the highlighted picture:
Open the Attribute inspector.
Under Button section, choose an image.
In the same section, change the State Config to Highlighted. Notice the image you chose under default is now gone and now you can set a new picture for the Highlighted.
Now you have a button with 2 state config and all you have to do during runtime to change the button.highlighted = true. Also, check the UIControl under Configuring the Control’s Attributes for more states.
You can also do it programatically as follows:
Swift (and almost the same in Objective-C):
// Setting the highlighted image
self.someButton.imageView?.highlightedImage = UIImage(named: "imageNameFromImageAssest")
// someButton will now some the highlighted image and NOT the image set in the IB
self.someButton.imageView?.highlighted = true

How to use multiple buttons in the same window?

Using XCode 3.2, What I'm trying to do is have the user input data and then they have three choices of what to do with that data, i.e. there are three different options or three buttons that I want to have in the same window. I can't figure out to have that coded...
right now i have one button that is activated using the
-(IBAction)buttonPressed
{ (formula)
}
how do I do this with multiple buttons?
I've looked for answers but they are a bit different than what Im looking for. Thank you so much!
while creating buttons set mybutton.tag=0;like this.change 0 to ur own and compare them in buttonpressed function
use sender to
-(IBAction)buttonPressed:(id)sender
{
UIButton *temp=(UIButton*)sender;
if([temp tag] == 0)
(formula)
//button 0
}
if([temp tag] == 1)
(formula)
button 1
}
}
Button press code should look like this:
- (IBAction)buttonPressed:(id)sender {
UIButton *senderButton = (UIButton *)sender;
if (senderButton == btnOK) {
// this is the OK button
} else if (senderButton == btnCancel) {
// this is the Cancel button
}
}
A better way, though, is probably to write three separate methods, and hook each one up to its corresponding button in IB.

IOS: one IBAction for multiple buttons

In my project I must control action of 40 buttons, but I don't want to create 40 IBAction, can I use only a IBAction, how?
If you're using interface builder to create the buttons, simply point them at the same IBAction in the relevant class.
You can then differentiate between the buttons within the IBAction method either by reading the text from the button...
- (IBAction)buttonClicked:(id)sender {
NSLog(#"Button pressed: %#", [sender currentTitle]);
}
...or by setting the tag property in Xcode and reading it back via [sender tag]. (If you use this approach, start the tags at 1, as 0 is the default and hence of little use.)
-(IBAction)myButtonAction:(id)sender {
if ([sender tag] == 0) {
// do something here
}
if ([sender tag] == 1) {
// Do something here
}
}
// in Other words
-(IBAction)myButtonAction:(id)sender {
switch ([sender tag]) {
case 0:
// Do something here
break;
case 1:
// Do something here
break;
default:
NSLog(#"Default Message here");
break;
}
Set all the buttons to use that one action. Actions generally have a sender parameter, which you can use to figure out which button is calling the action. One popular way to tell the difference between buttons is to assign a different value to each button's tag property. So you might have 40 buttons with tags ranging from 1 to 40. (0 probably isn't a great choice for a tag since that's what the default value is, and any button for which you forget to set the tag will have 0 as the tag value.)
This technique is most useful when all the buttons do approximately the same thing, like the buttons on a calculator or keyboard. If each of the buttons does something completely different, then you still end up with the equivalent of 40 methods, but you substitute your own switch statement for Objective-C's messaging system. In that case, it's often better just to spend the time to create as many actions as you need an assign them appropriately.
Sure. Just connect all buttons to the same action method in Interface Builder. Use the method's sender argument (possibly in conjunction with the buttons' tag property) to identify which button is sending the event.
Just use one IBAction and assign it to all your buttons.
Just used the above method myself , had a selection of buttons but converted them all and used switch case instead
-(IBAction)buttons:(id)sender
{
switch ([sender tag])
{
case 0 :
}
}
Seems like you are getting all the answers you need, but I wanted to add to everyone else's answers.
Whether you want to use one IBAction or 40 actions is up to what you want the buttons to do. If all the buttons do completely different things, you need all separate IBActions, but if you want all of them to do the same thing, you can use just one. I need more details of those buttons and action, but you probably have title for each button, so you can use that to differentiate each button and create a message or something that's being customized by the particular button pressed. Here is the example. Each time a button is pressed, a label displays a message that say "i.e.title of the button" pressed.
By doing it this way, you don't need to do switch case with all 40 patterns. You can still display or do something that's individualized by the button pressed with just 2-3 lines of code.
- (IBAction)button_Clicked:(UIButton *)sender {
//Get the buttons' titles.
NSString *title =[sender titleForState:UIControlStateNormal];
//Construct a message that includes the *title.
NSString *plainText=[NSString stringWithFormat:#"%# button pressed.", title];
//Assigns the *plainText to the label.
self.Label.text=plainText;
}
#end

Resources