int rand=((arc4random()%4)+1);
how would you go about making a touch event due to the numbers generated from int rand.
Example if the numbers generated are 1,2,2,3,4 and you have 4 buttons with a tag 1,2,3,4.
how would you make an event where you have to touch an object in order of the number generated by the int rand method?
Make 4 buttons give oneaction
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
rand=((arc4random()%4)+1);
}
-(IBAction)myMethod
{
switch (rand)
{
case 1:
//Do for first button tag
break;
case 2:
//Do for second button tag
break;
case 3:
//Do for third button tag
break;
case 4:
//Do for fourth button tag
break;
default:
break;
}
}
Related
I have multiple UISwitches on settings view, and linked all UISwitches to same IBAction function.
#IBAction func settingSwitchTapped(sender: AnyObject) {
}
How do i find which UISwitch is tapped so that i just save only the switch that actually changed (instead of saving all others also)
That's the sole purpose of the sender parameter.
If all your switches are defined as IBOutlets, you can compare sender to each of them in order to know which one you've tapped.
You can also give each of them a different tag property, and decide what to do based on sender.tag.
Set tag for each Switch with a unique no.
you can get exact switch by using following :
switch = sender.tag
Hope it helps
#IBAction func settingSwitchTapped(sender: AnyObject) {
switch (sender.tag){
case 101: // your tag
// executable code goes here
break;
case 102: // your tag
break;
case 103: // your tag
break;
default:
break;
}
}
I am having some trouble kicking-off with ReactiveCocoa
So basically - I have 2 (potentially N) UIButtons which when tapped on should trigger a different view to be displayed on the screen.
At the moment I am achieving it in the following way:
- (IBAction)firstButtonTapped:(id)sender {
[self processViewDisplayForViewType:ViewTypeFirstType];
}
- (IBAction)secondButtonTapped:(id)sender {
[self processViewDisplayForViewType:ViewTypeSecondType];
}
-(void)processViewDisplayForViewType:(ViewType)viewType{
switch (viewType) {
case ViewTypeFirstType:
//process showing a view based on the given type
break;
case ViewTypeSecondType:
//process showing a view based on the given type
break;
default:
break;
}
self.currentViewType = viewType;
}
Now, if I have other display types I would need to add aditional statements in the switch block... so I hope I can solve this using ReactiveCocoa and FRP. Anybody can point me in the right direction on solving this ?
I have an array of objects (scaleNotes) that are assigned to buttons that I would like to iterate through. I want the app to wait for the first set of buttons to be pressed, then to wait for the second, and so on. However, with the function I currently have the app freezes.
The method that contains the array:
-(void)fingerScale :(UIButton*)button1 :(UIButton*)button2 :(UIButton*)button3 :(UIButton*)button4 :(UILabel*)label {
Note *note = [[Note alloc]init];
for (int i = 0; i < [_scaleNotes count]; i++) {
note = _scaleNotes[i];
label.text = note.noteName;
[note waitForNote:button1 :button2 :button3 :button4 :note];
NSLog(#"Waiting... %i", i);
}
}
The "waitForNote" method:
-(void)waitForNote:(UIButton *)button1 :(UIButton *)button2 :(UIButton *)button3 :(UIButton *)button4 :(Note*)Note {
bool loop = YES;
while (loop) {
switch ([Note.fingering count]) {
case 0:
loop = NO;
break;
case 1:
button1 = Note.fingering[0];
if (button1.touchInside) {
loop = NO;
}
break;
case 2:
button1 = Note.fingering[0];
button2 = Note.fingering[1];
if (button1.touchInside && button2.touchInside) {
loop = NO;
}
break;
case 3:
button1 = Note.fingering[0];
button2 = Note.fingering[1];
button3 = Note.fingering[2];
if (button1.touchInside && button2.touchInside && button3.touchInside) {
loop = NO;
}
break;
default:
break;
}
}
}
I have been told that using addTarget:action:forControlEvents may solve my problem instead of using a while loop, but I am unsure about how to implement that into my code. Please help.
Your while loop is an infinite loop, and that's why your app appears to freeze. Most GUI systems -- iOS included -- won't work that way. You have to give the app's event loop, or run loop, time to gather and process events.
-addTarget:action:forControlEvents: will be part of the solution, but you really need to spend some time learning more about how apps and controls work in general. Briefly, your controls should be connected to appropriate actions; if you want to enforce some order for the buttons you might enable or disable some buttons as necessary.
To expand on Caleb's answer a little bit:
iOS, like most modern interactive OS'es, is event-driven.
You write code that responds to events. The OS detects events, and then invokes the methods in your app that respond to those events.
You do NOT write a while loop that keeps looping, waiting for things to happen.
For buttons, you create methods of type IBAction, and you connect them to your buttons (usually connected to a "touch up inside" event.) Then, when the user taps and releases a button, the system calls your action method.
For a slider, you would write an action method and attach it to the "value changed" event for the slider. Then, when the user changed the value of the slider the system would call you.
So for your buttons you would write an action method and attach it to your buttons. (It's more common to create buttons and attach them to actions in Interface Builder, but you can also create them in code and then attach them using the -addTarget:action:forControlEvents: method you mentioned.)
If you've got multiple buttons that do the same thing but with different values, you might want to attach all the buttons to the same IBAction method, and then put different tag values on each button. Then in your IBAction method, look at the tag on the sender (The button that invoked the action) and use that to figure out which button was pressed.
I have a segmented control (Added via story board) and have set two segments (set in story board). When it is clicked it fires my 'segmentedIndexChanged:' method, but in that method i can't get the values (it always returns null) for either .selectedSegmentedIndex or titleForSegmentedAtIndex
-(IBAction) segmentedIndexChanged {
NSLog(#"index, text value: %# , %#", self.mySegControl.selectedSegmentIndex, [mySegControl titleForSegmentAtIndex:mySegControl.selectedSegmentIndex]
);
switch (self.mySegControl.selectedSegmentIndex) {
case 0:
NSLog(#"segmented 1 selected");
break;
case 1:
NSLog(#"segmented 2 selected");
break;
default:
break;
}
}
any ideas why?
Are you sure the outlet is connected to the control? You can check by printing out NSLog(#"%#", self.mySegControl)
Also, usually, IBActions should have the form of - (IBAction)action:(id)sender, that way you would be able to access the sender (in this case the segmented control) without having an outlet to it as well.
In a mini flash game, I have a few different level select buttons, and they all attach to one "levelChange()" function, and I'm just wondering if there is an attribute that stores which button was pressed or how to determine which was pressed if not.
Thanks
try the currentTarget property of MouseEvent example:
function buttonClick(event:MouseEvent):void
{
trace(event.currentTarget);
}
I recommend you store your buttons in variables outside your function like so:
var levelOne:MovieClip = levelOne;
So you can later call upon them like this:
function buttonClick(event:MouseEvent):void
{
if (event.currentTarget == levelOne) {
trace("level one selected");
else if (event.currentTarget == levelTwo) {
trace("level two selected");
}
}
If you're using AS3 you can add a switch statement in your levelChange() function.
For example.... if you have 2 buttons, one with the instance name of "level1", and the other "level2".
function levelChange( me:MouseEvent ):void
{
switch( me.currentTarget.name )
{
case "level1":
// Go to Level 1 here.
case "level2":
// Go to Level 2 here.
}
}