How to disable button once clicked in iPhone programmatically - ios

I have made a footer with 5 buttons, I want to disable the button once clicked till another button is clicked (means once another button is clicked then button should be re enable it). I am posting my code.
code
UIButton *btn = (UIButton *)sender;
NSInteger index= btn.tag;
[self setNavigationBarButtons:index];
switch (btn.tag)
{
case 1: // all media type
{ btn.enable=No;
messageToBeEdit =nil;
}
break;
case 2: // image type
{ btn.enable=No;
messageToBeEdit = nil;
}
break;
case 3: // video type
{ btn.enable=No;
messageToBeEdit = nil;
}
break;
case 4: // text type
{ btn.enable=No;
// forth button
break;
}
break;
case 5: // audio type
{//fifth button
btn.enable=No;
messageToBeEdit = nil;
}
break;
My issue is I can't able to click once i have clicked it, I want to reenable it once another button is clicked.

- (void) tapButton:(id)sender {
UIButton *btn = (UIButton *)sender;
NSInteger index= btn.tag;
[self setNavigationBarButtons:index]
//first enable all the other buttons
for(UIButton *b in [[btn superview] subviews]) {
if([b isKindOfClass:[UIButton class]]) {
b.enabled = YES; //reenable
}
}
btn.enabled = NO; //then disable tapped button
}
You don't need switch case here, as you're already getting tapped button.

You need to keep references of All the buttons, (eg Button1, Button2.. etc)
In your switch case, enable all other buttons. For instance, if user tapped on Button1, then enable all other buttons like
button2.enabled = YES;
button3.enabled = YES;
button4.enabled = YES;
button5.enabled = YES;
A better approach would be to keep IBOutletCollection of all the buttons and loop through the array to enable all other buttons.

Related

Dynamic Radio Button in Objective C

I want to design a dynamic radio button in my app
for (int f = 0; f<arr.count; f++) {
UILabel *lbl = [[UILabel alloc]init];
lbl.frame = CGRectMake(radio_x+10,radio_y+5 , radio_w, radio_h);
lbl.text = arr[f];
lbl.textColor = [UIColor blackColor];
[self.sub_View addSubview:lbl];
self.yourButton = [[UIButton alloc] initWithFrame:CGRectMake(xPosOfTxt,radio_y , 20, 20)];
[self.yourButton setImage: [UIImage imageNamed:#"RadioButton-Selected.png"]forState:UIControlStateNormal];
[self.yourButton setImage: [UIImage imageNamed:#"RadioButton-Unselected.png"]forState: UIControlStateSelected];
[self.yourButton setTag:baseRadioTag+f];
[self.sub_View addSubview:self.yourButton];
[self.yourButton addTarget:self action:#selector(radioSelected:) forControlEvents:UIControlEventTouchUpInside];
}
-(void)radioSelected:(UIButton*)sender {
self.yourButton.selected = false;
sender.selected = !sender.selected;
self.yourButton = sender; }
I did like this , this is working like , selecting all the options , i want to select only one option at once , if I selected option 1 -> option 2 should be unselected . If I selected option 2 -> option 1 should be deselected.Please help me to do this .
First of all to make things easier
create a array which can hold reference of all the buttons
#interface ViewController ()
{
NSMutableArray *btnArray;
}
Create an object of Array
- (void)viewDidLoad {
[super viewDidLoad];
btnArray = [NSMutableArray new];
/// Here is your code for creating buttons
}
Now add all created buttons to this array
// this is last line from your code where you create your UI
[self.yourButton addTarget:self action:#selector(radioSelected:) forControlEvents:UIControlEventTouchUpInside];
// add this line to add your button to array
[btnArray addObject:self.yourButton];
}
Now when you click button radioSelected method is called
NOTE -: Here can be two cases according to me, but i don't know which one you require so i am explaining both of them
CASE FIRST :-When you select or deselect buttons final output can be that there can be no button selected(all can be deselected)
-(void)radioSelected:(UIButton*)sender{
// here if button is selected, deselect it otherwise select it
[sender setSelected:!sender.isSelected];
for (UIButton* btn in btnArray) {
// here we mark all other button as deselected except the current button
if(btn.tag != sender.tag){
// here when you deselect all button you can add a if statement to check that we have to deselect button only if it is selected
if(btn.isSelected){
[btn setSelected:NO];
}
}
}
}
CASE SECOND:-When atleast one button will be selected
-(void)radioSelected:(UIButton*)sender{
// here if current button is already selected we will not allow to deselect it and return
if(sender.isSelected){
return;
}
// here working is as same as described above
[sender setSelected:!sender.isSelected];
for (UIButton* btn in btnArray) {
if(btn.tag != sender.tag){
[btn setSelected:NO];
}
}
}
You can test both cases and use according to your requirement.
Hope this works for you.
And let me know if you face any issues :)

iOS how do I reset button images?

I have a few buttons that when pressed they change from a plain button to a button with a picture of a tick. The problem I have is that I can't then get a ticked button back to an untucked button when a separate button is pressed. Is this possible at all?
Here are my buttons:
- (IBAction)pickCat:(UIButton *)sender {
[self deselectAllButtons];
((UIButton *)sender).selected = true;
UIImage *btnImage1 = [UIImage imageNamed:#"white - on.png"];
[sender setImage:btnImage1 forState:UIControlStateNormal];
self.catLabel.text = #"WHITE (Hi-Po)";
}
- (IBAction)pickCatb:(UIButton *)sender {
[self deselectAllButtons];
((UIButton *)sender).selected = true;
UIImage *btnImage1 = [UIImage imageNamed:#"red - on.png"];
[sender setImage:btnImage1 forState:UIControlStateNormal];
self.catLabel.text = #"RED (Significant)";
}
- (IBAction)pickCatc:(id)sender {
UIImage *btnImage1 = [UIImage imageNamed:#"yellow - on.png"];
[sender setImage:btnImage1 forState:UIControlStateNormal];
self.catLabel.text = #"YELLOW (Serious)";
}
- (IBAction)pickCatd:(id)sender {
UIImage *btnImage1 = [UIImage imageNamed:#"green - on.png"];
[sender setImage:btnImage1 forState:UIControlStateNormal];
self.catLabel.text = #"GREEN (Important)";
}
- (void)deselectAllButtons
{
// assuming you have a reference to all your buttons
self->Btn1.selected = false;
self->Btn2.selected = false;
}
I like to set a different image for each state: normal and selected. It looks like you're using Interface Builder, and it's really easy to set up your buttons with different images for a normal and a selected state.
Then in your code you can do something like this:
- (IBAction)pickImage:(id)sender {
[self deselectAllButtons];
sender.selected = true;
self.locLabel.text = #"Red";
}
- (IBAction)pickImageb:(id)sender {
[self deselectAllButtons];
sender.selected = true;
self.locLabel.text = #"Red";
}
- (void)deselectAllButtons
{
// assuming you have a reference to all your buttons
self.btn1.selected = false;
self.btn2.selected = false;
...
}
If you want to be able to reset all buttons before changing one to a checked image, you have to have a reference to everything else you want to affect. If you want to get fancy, look into Outlet Collections so you can easily loop through an array of buttons from your IB file and set their selected state to false.
UPDATE:
Here's how your code should probably look:
- (IBAction)pickCat:(UIButton *)sender {
[self deselectAllButtons];
// no need to cast since you changed your method signature.
// the system now expects sender to be a button
// ((UIButton *)sender).selected = true;
sender.selected = true;
// no need to set the image explicitly. if you did things correctly
// in IB, you've already told the button which image to use when
// selected, and which image to use when not (default). when you set
// the line above (sender.selected = true), that will tell the button
// to go use the image that you added to the button's selected state in IB
// UIImage *btnImage1 = [UIImage imageNamed:#"white - on.png"];
// [sender setImage:btnImage1 forState:UIControlStateNormal];
self.catLabel.text = #"WHITE (Hi-Po)";
}
- (IBAction)pickCatb:(UIButton *)sender {
[self deselectAllButtons];
sender.selected = true;
self.catLabel.text = #"RED (Significant)";
}
- (IBAction)pickCatc:(id)sender {
[self deselectAllButtons];
sender.selected = true;
self.catLabel.text = #"YELLOW (Serious)";
}
- (IBAction)pickCatd:(id)sender {
[self deselectAllButtons];
sender.selected = true;
self.catLabel.text = #"GREEN (Important)";
}
- (void)deselectAllButtons
{
// 2 things:
// 1) I'm not sure about self->Btn1. why not self.Btn1?
// 2) it looks like you have 4 buttons (catA, catB, catC, catD). if so, you need to set the selected state for all of them to false
self->Btn1.selected = false;
self->Btn2.selected = false;
self->Btn3.selected = false;
self->Btn4.selected = false;
}

What is this button artefact when UIButton is selected?

I'm trying to make a UI Button a toggle button by using this code:
- (void)tapButton:(id)sender{
UIButton *button = sender;
if (!button.selected){
[self performSelector:#selector(highlight:) withObject:button afterDelay:0.0];
}else{
[self performSelector:#selector(removeHighlight:) withObject:button afterDelay:0.0];
}
}
- (void)highlight:(UIButton *)button{
button.selected = !button.selected;
button.highlighted = YES;
}
- (void)removeHighlight:(UIButton *)button{
button.selected = !button.selected;
button.highlighted = NO;
}
However, I'm getting a weird artefact when the button is in selected mode.
Not selected:
Selected:
Just make the button type to be "custom" instead of "system". I guess this weird bug is related to the new Tint feature on iOS7. It's probably buggy because your title property is an empty string #"".

Changing a UIButton to be turned off

I have a simple button with two images for each UIControlStates.
I want this button to behave as a control and as indicator so that I can press it down - "activate" and press again "deactivate", While some other functions can cause it to be turned off ("deactivate").
My question is how can I change it's state from selected to not-selected?
Changing the selected property would not do the trick :)
You can disable the button so it can't be press able.
yourButton.enabled = NO;
and When you want it back to be press able, then you can enabled it
yourButton.enabled = YES;
Simplest way would be consider button as switch and change it's state according switch on/off. For example use BOOL variable which upon button touch gets its value YES or NO while according to it button gets its image.
- (void) buttonTouched:(id)sender
{
switchOn = !switchOn;
UIImage *buttonImage = nil;
if (switchOn == YES)
{
buttonImage = [UIImage imageNamed:#"on.png"];
}
else
{
buttonImage = [UIImage imageNamed:#"off.png"];
}
[myButton setImage:buttonImage forState:UIControlStateNormal];
[myButton setImage:buttonImage forState:UIControlStateSelected];
}
if you need to programmatically set button "disabled":
- (void) setButtonDisabled
{
switchOn = YES; //calling buttonTouched: will turn it to NO
[self buttonTouched:nil];
}

UISegmentedControl Not functioning

Hi im trying to use segmented control to swap between three map views however its not working.
My IBAction method is as follows.
- (IBAction)segmentSwitch:(id)sender {
NSLog(#"inside segmented switch");
NSLog(#"selected segment %#",selectedSegment);
if (selectedSegment == 0) {
mapView.mapType = MKMapTypeStandard;
}
else{
mapView.mapType = MKMapTypeHybrid;
}
}
I have declared UISegementedControl as an outlet and connected it to the xib view. I have also connected this method with touch down/touch up inside/outside. It still doesn't print the NSLog commands given above. Which means this method is not accessed at all?
Quick summary of how to set up a UISegmentedControl in IB for those dealing with more than two segments:
IBOutlet UISegmentedControl *segmentControl; in #interface (or set it as #property)
- (IBAction)segmentedControlIndexChanged:(id)sender; in .h before #end
drag "Segmented Control" into view and change "Style" to Plain, Bordered, or Bar
increment # of "Segments"
Choose "Segment" and edit the "Title" making sure "Enabled" is checked
Connect your segmentedControl to Files Owner
Connect your segmentedControlIndexChanged: action and select "Value Changed" NOT "Touch up Inside"!!
add some code, maybe a switch statement if you have say 4 segments:
-(IBAction)segmentedControlIndexChanged:(id)sender {
NSLog(#"segmentedControlIndexChanged");
switch (segmentControl.selectedSegmentIndex)
{
case 0:
{
NSLog(#"dateSegmentActive");
dateSegmentActive = YES;
noteSegmentActive = NO;
typeSegmentActive = NO;
userIDSegmentActive = NO;
[yourTable reloadData];
}
break;
case 1:
{
NSLog(#"noteSegmentActive");
dateSegmentActive = NO;
noteSegmentActive = YES;
typeSegmentActive = NO;
userIDSegmentActive = NO;
[yourTable reloadData];
}
break;
case 2:
{
NSLog(#"typeSegmentActive");
dateSegmentActive = NO;
noteSegmentActive = NO;
typeSegmentActive = YES;
userIDSegmentActive = NO;
[yourTable reloadData];
}
break;
case 3:
{
NSLog(#"userIDSegmentActive");
dateSegmentActive = NO;
noteSegmentActive = NO;
typeSegmentActive = NO;
userIDSegmentActive = YES;
[yourTable reloadData];
}
break;
default:
break;
}
}
In recent iOS versions, you need the braces for each case: or you will get errors. This also shows some bool flagging to keep track of what segment is active, maybe for your willDisplayCell method.
Hope you have selected the right method ValueChanged and also you have connected the outlet of your method properly.
The only thing you need to do now is to replace your code with your code.
- (IBAction)segmentSwitch:(UISegmentedControl *)sender
{
NSLog(#"inside segmented switch");
NSLog(#"selected segment %d",sender.selectedSegmentIndex);
if (sender.selectedSegmentIndex == 0)
{
mapView.mapType = MKMapTypeStandard;
}
else
{
mapView.mapType = MKMapTypeHybrid;
}
}
Try replacing this code with your code.
Hope this helps you.
You should use the ValueChanged action for detecting the the switch of segments.
Is selectedSegment your UISegmentedControl?
Then you code should be like:
- (IBAction) segmentSwitch:(id)sender {
if (self.selectedSegment.selectedSegmentIndex == 0) {
mapView.mapType = MKMapTypeStandard;
} else{
mapView.mapType = MKMapTypeHybrid;
}
}

Resources