How to group radio buttons (from storyboard) in cocoa application? - objective-c

I'm trying to group 2 radio buttons in cocoa application.
but unlike in iOS, where you can connect the buttons with control-drag
(as shown in the picture)
in cocoa application I didn't find any elegant way to do so...
any suggesting before I do something ugly?

NSMatrix used to be the solution, but it is now discouraged:
NOTE: Use of NSMatrix is discouraged in apps that run in OS X v10.8
and later. If you need to create a radio button group in an app that
runs in OS X v10.8 and later, create instances of NSButton that each
specify a button type of NSRadioButton and specify the same action and
the same superview for each button in the group.
If all buttons call the same action method and are in the same supperview, Cocoa automatically selects the clicked button and deselects the previous button and -- no code necessary to do that.

I found this (maybe not elegant):
control-drag a single radio button to a create an sent-action.
control-drag the other button(s) to the same (empty) function.
You have to hover over the function to get it connected.
Now they are grouped.

so here is my not very elegant solution -
define array of buttons in the class:
NSArray* _radioButtonsArray;
initialize it in viewDIdLoad:
_radioButtonsArray = [[NSArray alloc] initWithObjects:_radioButton1,_radioButton2,_radioButton3, nil];
define a radioButtonIsPressed method and connect it to all radio buttons as an action:
-(IBAction)radioButtonIsPressed:(id)sender{
for (NSButton* btn in _radioButtonsArray){
if (btn != sender)
[btn setState:0];
}
}

I control-drag the single radio button to create an IBAction. Then I copy/past the radio button onto the same view. Now there are two with the same IBAction. Cocoa treats them as grouped.

Related

is single radio button available in cocoa?

I am trying to drag-drop a single radio button from object library in cocoa. But there is "radio group" object is available to drag-drop. In radio group has two radio button.
Is there any way to create a single radio button in cocoa application or hide the one radio button from radio group?
Thanks
You can make it one by going to attribute inspector and set the cell count to 1. but you have to handle the behaviour by your self logically.
Single radio button is not available in object library in cocoa. You can just use a normal UIButton and give its normal and selected images in Interface Builder.
Alternatively, you can just use a custom library for radio button like this one : https://github.com/onegray/RadioButton-ios
You should use a simple UIButton.
You can set different texts/images depending on a button status, like Devanshi suggested. The if/else approach is a bad idea though, because cocoa already provides these and are much more simple and small.
There are two ways, either storyboard (if you use it) or programatically, wherever you create your button (most likely viewDidLoad).
If you are using Storyboard
Storyboard is pretty straightforward, select your button, and under the "State" you can chose different settings. Each settings will actually load different parameters for the next settings. Like the title and image for example.
Just go on state "default" and set an unchecked box as image.
(You can)go on state "Highlighted" and set a temporary highlighted box as image; this is not mandatory.
Then go on state "Selected" and set a checked box as image.
And you're done.
If you are using only code
The programatic way to do this is fairly simple.
I assume we have a button called btSend,
UIControlStateNormal, UIControlStateSelected, UIControlStateDisabled, UIControlStateHighligted, are the states you can use. I used disabled and normal (enabled) here.
[self.btSend setImage:[UIImage imageNamed:#"SendIcon.png"] forState:UIControlStateNormal];
[self.btSend setImage:[UIImage imageNamed:#"SendIconGrayed.png"] forState:UIControlStateDisabled];
With this, you'll be up and running too.
After setting that up
Now that your buttons know what to show depending on their state, you need to add a selector method for your action (an IBAction), in which you will need to invert the state of your current button. You probably already have that, just add a boolean.
checkBoxSelected is a boolean that I created as an instance variable (on top of .m file). You can set it to "NO" in viewDidLoad if your radio is not selected by default, and to YES if it is selected by default.
#implementation TermViewController{
BOOL checkBoxSelected;
}
here is the method that is called when I press the button
- (IBAction)tapRadioButton:(id)sender {
checkBoxSelected = !checkBoxSelected;
[_btCheckbox setSelected:checkBoxSelected];
}
You probably have "something" that checks if your checkbox is selected, to know that, you can either get the state of your button by using self.yourButton.state. This will return a UIControlState, just check if it's Normal or Selected or Disabled or HIghlighted.
Or you can check the Boolean "checkboxselected" if it's YES or NO :)
If you have many radio buttons, you can save all those boolean values in a dictionary. the key would be your button number for example, and the object would be YES or NO. if you press the button, (like shown before), change the button state and also change it in the dictionary. At the end you have all your states in the dictionary.
I didn't explain all that in my first writing because that wasn't really a part of your question :) I hope this helps.
For radio button can use simple UIButton and maintain state of it and replace the image of on click event.
1) Declare globally in view
BOOL isChecked;
2) On button click event
if (isChecked)
{
[_btnRadioBox setImage:[UIImage imageNamed:#"chk_uncheck.png"] forState:UIControlStateNormal];
}
else
{
[_btnRadioBox setImage:[UIImage imageNamed:#"chk_check.png"] forState:UIControlStateNormal];
}
isChecked=!isChecked;
3) And get the status of it.
if (isChecked)
{
// Here write code of radio button when selected
}
else
{
// Here write code of radio button when unselected
}
You can use MVRadioButton to add animated radio button in iOS. This is very simple Drop in and easy to integrate Custom Control.
Its using CoreAnimation and Layers to Give it look and feel exactly like a Traditional Radio button that we have seen on Web.

Buttons as Outlets vs IBActions [Objective C + Xcode]

What is the point of ever setting a button as an outlet? I am following a tutorial and the teacher didn't really mention why he set a button as an outlet. A button is suppose to do an action/call a method and so we set it as an IBAction.
He sets the button as an outlet and then proceeds to change the text of the button through Xcode in viewDidLoad, but why not just keep it as an IBAction and change the text by using setTitle: forState:UIControlStateNormal ?
Isn't a button suppose to cause an action by definition?
in some logic cases you would need to change the behaviour of the button , e.g. upon invoking an action (triggered by other event )you will need to disable it or change its backgroundColor or text.
you don't have to set at all times , but in many cases it is really useful

3 programmatically created UIButtons - how to go between 3 UIViewControllers using those buttons with Storyboard?

Playing around with some Objective-C (well, iOS) and have done the following... loaded some UIButtons programmatically into a UIScrollView. That works well. Though I've always just connected UIViewControllers together using control-click and drag. Now I've created buttons programmatically, I have no idea how to go from one view controller to another in a Storyboard because there is nothing to drag from!
I'm not really sure what code to post as such, because I haven't done anything that /nearly/ works or doesn't work as such. I get how to do it with XIBs. But I suppose the question is : 3 UIButtons have been created programmatically and I have 3 UIViewControllers. How do I access those ViewControllers using my UIButtons?
Thanks
In the Interface builder view control click and drag from the viewcontroller icon under the first view controller, to the middle of the second view controller. A segue will be created, selected the appropriate type.
Now select the segue and in the inspector give it a unique identifier (say 'myNewSegue').
Now in your first viewcontroller you can create a method that has the following code:
-(void)myButtonAction:(id)sender {
[self performSegueWithIdentifier:#"myNewSegue" sender:self];
}
And add this method as a target action to your button:
[myButton addTarget:self
action:#selector(myButtonAction:)
forControlEvents:UIControlEventTouchUpInside];]
A segue doesn't have to have a button at the leading end of it; you can instead draw it from an entire view controller to another. You can also give a segue an identifier, a string that's used as a name for that segue. Once you've done that, you can programmatically trigger that segue by calling -performSegueWithIdentifier:sender:.
To actually call -performSegueWithIdentifier:sender:, though, you'll need to connect the button to a target and action. If you've never done that, read the Event Handling Guide for iOS in your documentation.

Interact with other views while a popover is active

I have a toolBar and I have setup two UIBarButtonItem on it. Both UIBarButtonItem are containing UIButtons as their customViews.
I activate a popover for their Touch Up Inside event as below,
[popover1 presentPopoverFromBarButtonItem:buttonItem1 permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
I have another UIButton named clearFilters inside the main view. (Also this is the view which is containing the above toolBar.) I have declared a method for clearFilters button's Touch Up Inside event.
My problem is,
I can not interact with the clearFilters button while a popover is active. So, I'm looking for a solution to interact with this clearFilters button, while a popover is active.
I tried by adding passthroughViews property for a popover as below and it do not work as I expect.
popover1.passthroughViews = [NSArray arrayWithObject:clearFiltersButton];
What could be the reason. As the documentation has mentioned I can not see any issue.
I expect if the above things are correct, then the Touch Up Inside event of the the clearFilters button's should be fire up.
So, please show me if there is any issue or a necessary way to work on this thing.
I'm working on XCode4 and iOS 4.3.
Thanks.
The UIPopoverController documentation reveals why the other bar buttons can be tapped while the popover is visible:
“When presenting the popover, this method adds the toolbar that owns the button to the popover’s list of passthrough views.”
Try querying and logging the popover’s passthrough views. Does it already have things in it? Perhaps something like this would work?
myPopover.passthroughViews = [myPopover.passthroughViews arrayByAddingObject:clearFilters];
I haven’t tested this code, but it’s worth a try.

How to connect a button to a method on Mac OS X

I am used to programming for the iPhone. There, I would connect a button to an action, and then a method by creating the method like so: -(IBAction) DoStuff{…}. Then I would make an outlet for the button, and then the actual button in Interface Builder. I would then connect the button to the outlet, and then connect the button to the action by clicking on the circle next to Touch Up Inside and drag it over to File's Owner and select my action.
I am new to programming for the Mac, so I tried to drag from performClick to the file I wanted, but it wouldn't let me make the connection. Do I have to do this programmatically or what? How do I get this button to trigger an action in my code?
The fundamental difference is that iOS controls can have multiple actions for different events, but Mac OS X controls only have one primary action (in some cases, there are others that can be set up programatically).
When you right-click on a button in a Mac nib, performClick: is under Received Actions; it’s not an event. The only entry under Sent Actions is “selector”, which is the only thing you can connect to an action on another object.
Because there is only one “sent event”, you’ll normally just control-drag/right-drag from the control to the target and select the action rather than control-clicking, selecting the event and dragging from that.
It works much the same, but unlike UIKit there is only one signature for actions:
- (IBAction)actionName:(id)sender;
See Communicating with Objects and Target/Action in Interface Builder for more.
I like to Control-Click on the button and then drag to the object that I want to recieve the action. I then select the method of possible choices from the popup menu.