iPhone - call UISwitch that is generated in a UIView when a button is pressed - iphone

To clarify my question, my program has three lightbulb on the screen (Customized UIButton)
when any lightbulb is pressed, I programatically generate a UIView with a switch on it
when I turn on the switch, corresponding lightbulb will light up (change its background image)
However, I have trouble accessing this UISwitch since I can't declare it publicly
My code goes something like this:
#property buttonA;
#synthesize buttonA;//all three buttons have their background image set to 'off.png'
- (IBAction)lightBulbPressed:(UIButton *)sender
{
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(1,1, 64, 64)];
UISwitch *mySwitch = [[UISwitch alloc] initWithFrame:CGRectMake(0,0,64,64)];
[mySwitch addTarget:self action:#selector(onOrOff) forControlEvents:UIControlEventValueChanged];
[myView addSubview:mySwitch]
[self.view addSubview:myView];
}
So what troubles me is how to program the selector onOrOff, so that it knows which switch is being touched and change the background image of corresponding button accordingly.

Think about your method:
- (IBAction)lightBulbPressed:(UIButton *)sender {
// your method
}
You already know who called it. This piece of information is stored in sender.
So you can save it and use later in onOrOff
By the way, if you are using UISwitch you have to check
UIControlEventValueChanged
and not UIControlEventTouchUpInside.
EDIT: To pass your sender you can store its value to a NSString *buttonTapped declared in your .h file
- (IBAction)lightBulbPressed:(UIButton *)sender {
if (sender == bttOne) {
buttonTapped = #"ButtonOneTapped";
} else if (sender == bttTwo) {
buttonTapped = #"ButtonTwoTapped";
} else if (sender == bttThree) {
buttonTapped = #"ButtonThreeTapped";
}
// your method
}
- (void)onOrOff {
if ([buttonTapped isEqualToString:#"ButtonOneTapped"]) {
// Button One
} else if ([buttonTapped isEqualToString:#"ButtonTwoTapped"]) {
// Button Two
} else if ([buttonTapped isEqualToString:#"ButtonThreeTapped"]) {
// Button Three
}
}

One way to do so, is taht you give them distinct tag numbers in IB, and in - (IBAction)lightBulbPressed:(UIButton *)sender method, get their tag. e.g. NSInteger pressedButtonTag = [sender tag];, and go from there.
Also, instead of alloc/init myView every time user presses a button, you can add that view in IB, add the switch to it, put in the hierarchy of the owner but not the view, and set an outlet to it in .h. Call it whenever you need it, and again, access the switch by tag e.g. ( UISwitch *mySwitch = (UISwitch *)[myView viewWithTag:kSwitchTag]; ) and do whatever you want to do (on or off), add it to the subview and remove it later. This is more efficient.

Related

how to pass parameter when different button call same class?

I am developing for iPhone the app I am developing has many buttons and I want all buttons to call the same class but with different parameter
for example I want button1 to call the displayimageclass
and button2 should call the same class displayimageclass so, how to different method call same class and in that same class how to fetch different button from where it is call to particular class.
That is pretty much standard. Just define as many IBAction methods as you need.
In the viewController's .h file:
- (IBAction)actionButton1:(UIButton *)sender;
- (IBAction)actionButton2:(UIButton *)sender;
- (IBAction)actionButton3:(UIButton *)sender;
And in its .m file:
{
//react here to button1 pressed
}
- (IBAction)actionButton1:(UIButton *)sender
{
//react here to button1 pressed
}
- (IBAction)actionButton2:(UIButton *)sender
{
//react here to button2 pressed
}
- (IBAction)actionButton3:(UIButton *)sender
{
//react here to button3 pressed
}
Then associate the action with the Button's events (TouchUpInside would be most appropriate, I guess).
You should add tag property to your buttons.
Suppose your buttons are
button1.tag =1;
button2.tag =2;
button3.tag =3;
When you click any button, NSLog shows related button tag number. i.e You will get your result what you want.
- (IBAction)buttonClicked:(id)sender {
UIButton* button = (UIButton *)sender;
NSLog(#"The number of tag:%d",button.tag);
}
I think it will be helpful to you.
you can implement your action method like this:
- (IBAction)action:(UIButton *)sender
{
//sender will be different for different button
}
Set tag value for buttons and get those buttons like
- (IBAction)action:(UIButton *)sender
{
UIButton *btn = (UIButton*)sender;
}
Are you looking for
1) several buttons performing the same method with the same behavior
2) several buttons performing the same method but having different behavior based on the button characteristics
3) each button performing its own method.
1) You can register several buttons on the same IBAction, they all will call it and perform the same code
2) In the method were all the buttons are registered (cf: 1) it is possible to sort the buttons by subclassing the UIButton class, giving an enum value that represents what the button should perform and then in the called method check the enum value with a switch in order to trigger the wanted behavior
The UIBarButtonItem already has this tag property so you could use them by giving a value to each of your UIBarButtonItem in the Interface Builder and set them to call the following method
- (IBAction) myButtonsMethod:(id)object
if ([object isKindOfClass:[UIBarButtonItem class]])
{
switch ([(UIBarButtonItem *)object tag])
{
case myFirstTagValue
...
}
3) #Hermann Klecker solution is the right one.

KVO with two UIButtons

I have a custom UITableViewCell subclass that gets presented in a UITableView in a UIPopoverController. The UIPopoverController is presented from a UIBarButtonItem.
When selections in the UITableViewCell are made, I send a NSNotification to the UIViewController class that is presenting the UIPopoverController. The selections in the table update my view in my viewController.
Now, there is a requirement to have another UIBarButtonItem that does EXACTLY the same thing as one of the buttons in the UITableViewCell in the popover. Basically the use case is that this feature seems to be the most commonly used feature in our popover and they want an easy way to just turn it on and off from another button.
So what I did was create a new UIBarButtonItem, and have a target attached to it:
- (void)FilterOn:(id)sender {
isFilterOn = !isFilterOn;
if ([sender isKindOfClass:[UIBarButtonItem class]]) {
UIBarButtonItem *filter = (UIBarButtonItem *)sender;
if (isFilterOn) {
[filter setTitle:#"Filter On"];
[self DoFilter];
}
else {
[aboutMeBBI setTitle:#"Filter Off"];
[self ClearFilter];
}
}
}
So this part works. It updates the model, the title of the button changes. The problem is, let's say I turn filter on, then in the popover, I turn the filter off. I pass the notification to my viewController class to its normal update method that handles filtering and a bunch of other stuff. I added this simple snippet to when the filter button is pressed from the popover:
- (void)FilterSortOptionDidSelect:(NSNotification *)notification {
NSDictionary *userDict = [notification userInfo];
NSInteger theTag = [[userDict objectForKey:#"CellTag"] integerValue];
switch (theTag) {
case FILTER: {
// update Model
[self.FilterBarButtonItem setTitle:#"Filter off"];
}
break;
default:
break;
}
}
This isn't quite what I want though since if I click back on the filter button since for starters, if I click back on the Filter button, it'll still say Filter Off, and do the action for Filter Off, and then if I click it again, it'll do Filter on actions. I try to fake it in the switch statement by changing the title, but that isn't really what I want to do. I read a little about key value observing and I wasn't sure if I could use something like that here, to register my buttons state with that of a button in a UITableViewCell subclass in a UIPopoverController. If anyone has any ideas that would be great. Thanks.

Objective C Syntax: addTarget on UISwipeGestureRecognizer

I'm currently working on an app where the user has the option to either swipe through data, or use a button to go through the data. I'm having trouble understanding how to combine two bits of code.
Here is the code I'm using for swiping:
- (void)swipeRight:(UISwipeGestureRecognizer*)recognizer
{
if ([questions hasPrevQuestion] == YES) {
[self vorige:nil];
}
}
(the [self vorige:nil]; is calling the method for the button, so the swiping and the button have the same behavior)
and I need to somehow incorporate this code which applies to the button:
-(void)animationDidEndOnAnswer {
[vorigeButton addTarget:self action:#selector(newQuestion:) forControlEvents:UIControlEventTouchUpInside];
}
I think it's pretty simple, but I just cannot for the life of me figure out how to call the swiping method place of the button here...I'm thinking it's simple because I found this example in the UIGestureRecognizer class reference:
- (void)addTarget:(id)target action:(SEL)action
but being new to objective-c, I don't really know what to do with this. any help is very appreciated.
- (void)addTarget:(id)target action:(SEL)action is the code equivalent of binding a button action to a method like you do when you ctrl-drag from a button to an IBAction in Interface Builder.
So if your method is called vorige: and you want it to be called when the button is tapped, you would say:
[vorigeButton addTarget:self action:#selector(vorige:) forControlEvents:UIControlEventTouchUpInside];
But I don't know why you would want to do that as a result of an animation - you normally would set the button action once when the view is loaded, not change it during an animation.
Nick's solution is good.
if you want to call the same method for the swiping & the tap on your button, you can tweak your swipeRight like this:
- (void)goThrougtData:(id)sender
{
if( [sender isKindOfClass:[UISwipeGestureRecognizer class]] ) {
// swipe specific code
}
else if( [sender isKindOfClass:[UIButton class]] ) {
// tap specific code
}
if ([questions hasPrevQuestion] == YES) {
[self vorige:nil];
}
}
and in your init method, you add
[mySwipeRecognizer addTarget:self action:#selector(vorige:)];
[vorigeButton addTarget:self action:#selector(vorige:) forControlEvents:UIControlEventTouchUpInside];

iOS / iPhone- Hiding one button when another is clicked

I have a settings view in my app which has a couple of buttons (actually UISwitches). If the "off" setting on one of the switches is selected, I'd like to hide the second switch immediately. Can this be done?
IBOutlet UIButton *btn1;
IBOutlet UIButton *btn2;
write the above 2 lines in your .h file and set the outlets with XIB.
Now create a method called hideButton
-(IBAction)hideButton
{
btn1.hidden = YES;
}
in XIB attach this method with btn2.
So now when you click on btn2 it will hide btn1.
Connect the two switches as outlets. lets say switch1 & switch2.
Connect this function to the valueChanged action.
- (IBAction)mySwitch1:(id)sender {
[switch2 setHidden:!(switch1.isOn)];
}
Now when switch1 is not on then switch2 will be hidden.
Add a target to the first switch which on value change calls the instance of the second switch and hides it.
Add the target:
[switch1 addTarget:self action:#selector(switchToggled:) forControlEvents: UIControlEventValueChanged];
Calls this method:
- (void) switchToggled:(UISwitch*)switch {
if ([switch isOn]) switch2.hidden = YES;
else switch2.hidden = NO;
}
NJones if statement is more effective though.
Swift 4
Within your function do the following:
btn1.isHidden = true

changing a button's text from another method when the buttons are in a subclass?

How do you access a button that's in a subview of a view?
I have a viewController 'GamePlay', which has a scrollview in it called 'gameScroll'. Within this scrollview I have about 100 buttons, each with a tag, and I want to be able to change the text of the button from another method.
- (void) viewDidLoad {
//Created buttons in a for-loop, assigning each a tag
//numOfButtons is total number of buttons created
}
I imagine it would be something like this? but I cant seem to find an answer on exactly how i do it when the button is in a subview
- (void) otherMethod {
for (int i=0; i<numOfButtons; i++) {
// tagsForAction = get list of buttons that need to be changed from another array
for (j=0; j<tagsForAction.length; j++) {
intTagForAction = [tagsForAction objectAtIndex:j];
if (i = tagForAction) {
UIButton* button = [Gameplay.gameScroll.view viewWithTag:tagForAction];
button.title = #"A";
}
}
}
}
I know this code isnt totally right. Im just giving you an idea of the process. I can do everything except this part in the if statement:
UIButton* button = [Gameplay.gameScroll.view viewWithTag:tagForAction];
button.title = #"A";
so how do I change the text of these buttons?
NSArray *subViewList = [gameScroll subviews];
for (id button in subViewList)
{
if ([button isKindOfClass:[UIButton class]])
{
[button setTitle:#"OK" forState:UIControlStateNormal];
}
}
Try this code
You don't have to use the for loop like that, you can get an array of subviews from any view by doing something like [someView subviews]. So, inside of your otherMethod function you can do something like:
for (UIView *v in [gameScroll subviews]) {
if (v.tag == <some_int_here>) {
[v setTitle:#"Some other title" forState:UIControlStateNormal];
}
}
I'm not exactly sure what your criteria is for determining which buttons inside the gameScroll view have to get updated, but you can work from here.