UISwitch double tap - ios

I currently have a UISwitch that when turned on and off increments and decrements a counter respectively.
When the counter is at 0 the counter will not decrement. Functionally, this works perfectly however I have noticed a bug and wondered if anyone has experienced this.
Essentially if you very very quickly double tap the UISwitch at its far position (fully on or off) the counter will increment twice as I'm imagining the UISwitch isn't fully hitting the off state and is therefore simply adding to the counter again without first decrementing it.
Here's the code I'm using to do the checks on the switch:
// Sliders modified
- (IBAction)personalityChanged:(id)sender {
if ([personality isOn] ){
[[[GlobalData sharedGlobalData]personalitySliderValue] replaceObjectAtIndex:currentRecord-1 withObject:#"1"];
rating ++;
NSLog(#"The value of personality slider is %#", [[[GlobalData sharedGlobalData]personalitySliderValue] objectAtIndex:currentRecord-1]);
[personality set]
}
else {
[[[GlobalData sharedGlobalData]personalitySliderValue] replaceObjectAtIndex:currentRecord-1 withObject:#"0"];
[self subtractFromRating:nil];
NSLog(#"The value of personality slider is %#", [[[GlobalData sharedGlobalData]personalitySliderValue] objectAtIndex:currentRecord-1]);
}
[self checkRating:nil];
}
Then the subtract rating:
// subtract from rating
-(void)subtractFromRating:(id)sender{
if (rating == 0) {
// do nothing
}
else
{
rating --;
}
}
And finally the result of what happens if the slider is in a position:
// check rating
-(void)checkRating:(id)sender{
switch (rating) {
case 0:
[matchRating setText:#""];
[ratingGraphic setImage:[UIImage imageNamed:#""]];
NSLog(#"rating is 0");
break;
case 1:
[matchRating setText:#"Single Match"];
[ratingGraphic setImage:[UIImage imageNamed:#"ratinggraphic1.png"]];
NSLog(#"rating is 1");
break;
case 2:
[matchRating setText:#"Potential Match"];
[ratingGraphic setImage:[UIImage imageNamed:#"ratinggraphic2.png"]];
NSLog(#"rating is 2");
break;
case 3:
[matchRating setText:#"Great Match"];
[ratingGraphic setImage:[UIImage imageNamed:#"ratinggraphic3.png"]];
NSLog(#"rating is 3");
break;
case 4:
[matchRating setText:#"Hot Match"];
[ratingGraphic setImage:[UIImage imageNamed:#"ratinggraphic4.png"]];
NSLog(#"rating is 4");
break;
default:
break;
}
}
Is there a way to make sure the switch goes from the on state to the off fully before returning or a better approach for this?

A solution to detect if there has actually been a change is to keep an additional BOOL variable that keeps track of the last switch state.
BOOL lastValue = NO; // initial switch state
- (IBAction)personalityChanged:(id)sender {
if (personality.isOn != lastValue) {
lastValue = personality.isOn;
if ([personality isOn] ){
[[[GlobalData sharedGlobalData]personalitySliderValue] replaceObjectAtIndex:currentRecord-1 withObject:#"1"];
rating ++;
NSLog(#"The value of personality slider is %#", [[[GlobalData sharedGlobalData]personalitySliderValue] objectAtIndex:currentRecord-1]);
[personality set]
}
else {
[[[GlobalData sharedGlobalData]personalitySliderValue] replaceObjectAtIndex:currentRecord-1 withObject:#"0"];
[self subtractFromRating:nil];
NSLog(#"The value of personality slider is %#", [[[GlobalData sharedGlobalData]personalitySliderValue] objectAtIndex:currentRecord-1]);
}
[self checkRating:nil];
}
}
This will then only perform when the switch state has actually changed.

Related

How to change image on button?

I have two bottom left (<) side button and right (>) button. I have to change the images from array with left and right button action?
Code :
- (IBAction)onClickRightLeft:(id)sender {
switch ([sender tag]) {
case 10:
indexValueL++;
if(indexValueL >= 3)
{
indexValueL = 2;
}
if(indexValueL < 0)
{
indexValueL=0;
}
[imgViewStory setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#",[[[[arrGlobal objectAtIndex:indexValueL] valueForKey:#"FeaturedStoryImage"]]]];
break;
case 20:
indexValueR++;
if(indexValueR >= 3)
{
indexValueR = 2;
}
if(indexValueR < 0)
{
indexValueR=0;
}
[imgViewStory setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#",[[[[arrGlobal objectAtIndex:indexValueR] valueForKey:#"FeaturedStoryImage"]]]];
break;
default:
break;
}
How do I manage an array index?
I think this should do.. (not tested)
- (IBAction)onClickRightLeft:(id)sender {
switch ([sender tag]) {
case 10: // considering right clicked
indexValue++;
break;
case 20: // considering left clicked
indexValue--;
break;
}
if(indexValue >= 3)
{
indexValue = 0;
}
if(indexValue < 0)
{
indexValue=2;
}
[imgViewStory setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#",[[[[arrGlobal objectAtIndex:indexValue] valueForKey:#"FeaturedStoryImage"]]]];
Also while showing image, you should consider it caching & asynch loading. Check this for more info

swiping right, the page control's current page changes but the dots don't

I created a tutorial by some consequential images and added a page control on it. In addition, I added a swipe gesture which responds by changing the picture. In the code below, a switch case is defined in order to decide which image and dot should be the next according to the direction of swiping (left/right).
- (IBAction)handleSwipe:(UISwipeGestureRecognizer *)sender
{
// NSLog(#"swiped");
NSArray *images;
if (self.selectedRow == 0) {
images = [[NSArray alloc] initWithObjects:#"w8.JPG",#"w7.JPG",#"w6.JPG",#"w5.JPG",#"w4.JPG",#"w3.JPG", #"w2.JPG", #"w1.JPG" ,#"w9.JPG", nil];
self.pageControl.hidden = NO;
[self.pageControl setNumberOfPages:9];
UISwipeGestureRecognizerDirection direction = [(UISwipeGestureRecognizer *) sender direction];
switch (direction) {
case UISwipeGestureRecognizerDirectionRight:
if (pageController == 0 || imageIndex == 8)
{
self.Oops = [[UIAlertView alloc] initWithTitle:#"Oops!" message:#"You cannot swipe to the left, there are not any previous steps." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[self.Oops show];
}
else {
[self.pageControl setCurrentPage:pageController - 1];
pageController = pageController - 1;
}
imageIndex++;
break;
case UISwipeGestureRecognizerDirectionLeft:
if (pageController < 8 && pageController >= 0) {
[self.pageControl setCurrentPage:pageController];
pageController = pageController + 1;
}
else {
[self.pageControl setCurrentPage: pageController ];
pageController = 0;
}
imageIndex--;
break;
default:
break;
}
NSLog(#"pagecontroller is %li and imageIndex is %li " , pageController, imageIndex);
imageIndex = (imageIndex < 0) ? ([images count] - 1): imageIndex % [images count];
self.imageView.image = [UIImage imageNamed:[images objectAtIndex:imageIndex]];
}
As you see in the code, there is a NSLog; when I run the app, everything works properly but when I swipe to the right to see a previous image, Although NSLog shows that all indexes of dots and images change correctly and we see the previous image, the dots don't change. Swiping to the right again, the dots change but it's late because the order of the images and dots that must be classified becomes disordered for example the last image is shown with the first dot.
I'm sure that my algorithm is correct, because I checked it with that NSLog, and also everything works fine before swiping to the right.
Any ideas?
I have changed the code a bit:
switch (direction) {
case UISwipeGestureRecognizerDirectionRight:
if (pageController != 0 && imageIndex != 9) {
[self.pageControl setCurrentPage:(pageController - 1)];
pageController --;
imageIndex++;
}
break;
case UISwipeGestureRecognizerDirectionLeft:
if (pageController <= 8 && pageController >= 0) {
[self.pageControl setCurrentPage:pageController];
pageController = pageController + 1;
imageIndex--;
}
break;
default:
break;
}
Now the only problem is that the page control counts the current dot twice when I swipe to a different direction.
Your imageIndex++ and imageIndex-- lines are in the wrong place. (You presumably don't want to change image if pageController is already 0, for example). Move them to:
- (IBAction)handleSwipe:(UISwipeGestureRecognizer *)sender
{
// NSLog(#"swiped");
NSArray *images;
if (self.selectedRow == 0) {
images = [[NSArray alloc] initWithObjects:#"w8.JPG",#"w7.JPG",#"w6.JPG",#"w5.JPG",#"w4.JPG",#"w3.JPG", #"w2.JPG", #"w1.JPG" ,#"w9.JPG", nil];
self.pageControl.hidden = NO;
[self.pageControl setNumberOfPages:9];
UISwipeGestureRecognizerDirection direction = [(UISwipeGestureRecognizer *) sender direction];
switch (direction) {
case UISwipeGestureRecognizerDirectionRight:
if (pageController == 0 || imageIndex == 8)
{
self.Oops = [[UIAlertView alloc] initWithTitle:#"Oops!" message:#"You should turn over to the left." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[self.Oops show];
}
else {
[self.pageControl setCurrentPage:pageController - 1];
pageController = pageController - 1;
imageIndex++;
}
break;
case UISwipeGestureRecognizerDirectionLeft:
if (pageController < 8 && pageController >= 0) {
[self.pageControl setCurrentPage:pageController];
pageController = pageController + 1;
imageIndex--;
}
else {
[self.pageControl setCurrentPage: pageController ];
pageController = 0;
}
break;
default:
break;
}
NSLog(#"pagecontroller is %li and imageIndex is %li " , pageController, imageIndex);
imageIndex = (imageIndex < 0) ? ([images count] - 1): imageIndex % [images count];
self.imageView.image = [UIImage imageNamed:[images objectAtIndex:imageIndex]];
}
In your amended code, I think you need to set the page control differently (to pageController+1) for swipe left:
switch (direction) {
case UISwipeGestureRecognizerDirectionRight:
if (pageController != 0 && imageIndex != 9) {
[self.pageControl setCurrentPage:(pageController - 1)];
pageController --;
imageIndex++;
}
break;
case UISwipeGestureRecognizerDirectionLeft:
if (pageController <= 8 && pageController >= 0) {
[self.pageControl setCurrentPage:pageController+1];
pageController = pageController + 1;
imageIndex--;
}
break;
default:
break;
}

Randomizing Square colors [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have four squares on my screen and I want each of the squares to display a different image every time for each square. I have got it to work, but as the code repeats sometimes there is a delay. I'm not sure what I'm doing wrong.
Here is my main code
#import "HomeScreenViewController.h"
#interface HomeScreenViewController ()
#end
#implementation HomeScreenViewController
-(void)startRandomSquares
{
self.greenImage = [UIImage imageNamed:#"GreenSquare.png"];
self.redImage = [UIImage imageNamed:#"RedSquare"];
self.blueImage = [UIImage imageNamed:#"BlueSquare"];
self.purpleImage = [UIImage imageNamed:#"PurpleSquare"];
self.arrayOfColors = [NSMutableArray arrayWithObjects:self.greenImage,self.redImage, self.blueImage, self.purpleImage, nil];
}
-(IBAction)Button1:(id)sender
{
self.startLabel.hidden = YES;
}
-(IBAction)Button2:(id)sender
{
}
-(IBAction)Button3:(id)sender
{
}
-(IBAction)Button4:(id)sender
{
}
-(void)randomizeAllSquares
{
[self randomizedSquare1];
[self randomizedSquare2];
[self randomizedSquare3];
[self randomizedSquare4];
}
-(void)randomizedSquare1
{
[self startRandomSquares];
randomColor = arc4random() % [self.arrayOfColors count];
square1RandomNumber = randomColor;
// NSLog(#"Square 1 : %d", square1RandomNumber);
//NSLog(#"Square 1 colors : %#", self.arrayOfColors);
switch (square1RandomNumber) {
case 0:
self.square1.image = self.arrayOfColors[0];
break;
case 1:
self.square1.image = self.arrayOfColors[1];
break;
case 2:
self.square1.image = self.arrayOfColors[2];
break;
case 3:
self.square1.image = self.arrayOfColors[3];
break;
default:
break;
}
if (square1RandomNumber == square2RandomNumber ) {
[self randomizedSquare1];
NSLog(#"Square 1-2 MATCH!!!");
}
if (square1RandomNumber == square4RandomNumber) {
[self randomizedSquare1];
NSLog(#"Square 1-4 Match!!!");
}
}
-(void)randomizedSquare2
{
[self startRandomSquares];
randomColor = arc4random() % [self.arrayOfColors count];
square2RandomNumber = randomColor;
//NSLog(#"Square 2 : %d", square2RandomNumber);
//NSLog(#"Square 2 colors : %#", self.arrayOfColors);
switch (square2RandomNumber) {
case 0:
self.square2.image = self.arrayOfColors[0];
break;
case 1:
self.square2.image = self.arrayOfColors[1];
break;
case 2:
self.square2.image = self.arrayOfColors[2];
break;
case 3:
self.square2.image = self.arrayOfColors[3];
break;
default:
break;
}
if (square2RandomNumber == square1RandomNumber ) {
[self randomizedSquare2];
NSLog(#"Square 2-1 Match!!!");
}
if (square2RandomNumber == square4RandomNumber) {
[self randomizedSquare2];
NSLog(#"Square 2-4 Match!!!");
}
}
-(void)randomizedSquare3
{
[self startRandomSquares];
randomColor = arc4random() % [self.arrayOfColors count];
square3RandomNumber = randomColor;
//NSLog(#"Square 3 : %d", square3RandomNumber);
//NSLog(#"Square 3 colors : %#", self.arrayOfColors);
switch (square3RandomNumber) {
case 0:
self.square3.image = self.arrayOfColors[0];
break;
case 1:
self.square3.image = self.arrayOfColors[1];
break;
case 2:
self.square3.image = self.arrayOfColors[2];
break;
case 3:
self.square3.image = self.arrayOfColors[3];
break;
default:
break;
}
if (square3RandomNumber == square2RandomNumber ){
[self randomizedSquare3];
NSLog(#"Square 3 - 2 MATCH!!!");
}
if (square3RandomNumber == square1RandomNumber) {
[self randomizedSquare3];
NSLog(#"Square 3- 1 MATCH!!");
}
}
-(void)randomizedSquare4
{
[self startRandomSquares];
randomColor = arc4random() % [self.arrayOfColors count];
square4RandomNumber = randomColor;
//NSLog(#"Square 4 : %d", square4RandomNumber);
//NSLog(#"Square 4 colors : %#", self.arrayOfColors);
switch (square4RandomNumber) {
case 0:
self.square4.image = self.arrayOfColors[0];
break;
case 1:
self.square4.image = self.arrayOfColors[1];
break;
case 2:
self.square4.image = self.arrayOfColors[2];
break;
case 3:
self.square4.image = self.arrayOfColors[3];
break;
default:
break;
}
if (square4RandomNumber == square2RandomNumber ) {
[self randomizedSquare4];
NSLog(#"Square 4-2 MATCH!!");
}
if (square4RandomNumber == square1RandomNumber) {
[self randomizedSquare4];
NSLog(#"SQuare 4-1 MATCH!!");
}
if (square4RandomNumber == square3RandomNumber) {
[self randomizedSquare4];
NSLog(#"Square 4-3 Match");
}
}
Ouch, that's a lot of code duplication. In general if you find yourself writing a similar piece of code multiple times it's not just best practice to generalize it, but you'll likely end up with a better solution.
A simple shuffle function on your array along with a simple reassign would work, and will give a runtime of N (ie the loop will only go through the array once per call). What you have now will technically try to create the color for a square multiple times in the case that it finds a match which is the reason for your slowness. Square 4 has a 3/4 chance that it will get the same color as another square so it likely runs at least 3 times before stopping.
- (void)shuffleImages
{
//uses the Fisher-Yates shuffle algorithm
for (NSUInteger i = self.arrayOfColors.count - 1; i >= 1; i--)
{
int index = arc4random_uniform(i+1);
[self.arrayOfColors exchangeObjectAtIndex:index withObjectAtIndex:i];
}
}
- (void)updateImages
{
[self shuffleImages];
self.square1.image = self.arrayOfColors[0];
self.square2.image = self.arrayOfColors[1];
self.square3.image = self.arrayOfColors[2];
self.square4.image = self.arrayOfColors[3];
}
All you need to do when you want your colors to change is call the updateImages function.
The delay comes from the check at the end of each randomisation. There's a 75% chance the number generated is in one of the other 3 squares, so it will loop and loop until it generates the only number it can be.
A better solution would be to shuffle the array of images, and then assign each image to each view in order.
e.g. (pseudo-code)
shuffle array of images
view 1 = array[0]
view 2 = array[1]
...
view 4 = array[3]
Brandon is right about the insane amount of code duplication, and using the fischer-yates algorithm is definitely the right way to go, but it sounds like you also want this to repeat, so you should use an NSTimer.
#property (strong, nonatomic) NSTimer *randomizeColorTimer;
- (void)startRandomizing
{
_randomizeColorTimer = [NSTimer scheduledTimerWithTimeInterval:0.25
target:self
selector:#selector(shuffleImages)
userInfo:nil
repeats:YES];
}
- (void)stopRandomizing
{
[_randomizeColorTimer invalidate];
_randomizeColorTimer = nil;
}

Display array of Images in UIImageView

array of images added into Project
imaging is the UIImageView and imagg is Image choosen by user its default
_imaging.image=imagg;
arr = [NSArray arrayWithObjects:
[UIImage imageNamed:#"1.jpg"],
[UIImage imageNamed:#"2.jpeg"],
[UIImage imageNamed:#"3.jpeg"],
[UIImage imageNamed:#"4.jpeg"],
[UIImage imageNamed:#"5.jpeg"],
nil];
assume user selected third image i.e 3.jpeg i am showing the 3.jpeg in imageview. Then using two button actions respectively Next and Previous next or previous images 3.jpeg should display.
- (IBAction)previous:(id)sender {
////
}
- (IBAction)next:(id)sender {
//////
}
}
for the next action its starting from 2nd image even for previous action its starting from 1st image.
this is the simple concept, this is working in static method, but working fine
assign the one global variable
#property (strong,nonatomic) NSString *imagestr;
- (IBAction)previous:(id)sender {
int str=[imagestr integerValue];
NSLog(#"the int value==%d",str);
switch (str) {
case 0:
_imaging.image=[arr objectAtIndex:4];
imagestr=#"4";
break;
case 1:
_imaging.image=[arr objectAtIndex:0];
imagestr=#"0";
break;
case 2:
_imaging.image=[arr objectAtIndex:1];
imagestr=#"1";
break;
case 3:
_imaging.image=[arr objectAtIndex:2];
imagestr=#"2";
break;
case 4:
_imaging.image=[arr objectAtIndex:3];
imagestr=#"3";
break;
default:
break;
}
}
- (IBAction)next:(id)sender {
int str=[imagestr integerValue];
NSLog(#"the int value==%d",str);
switch (str) {
case 0:
_imaging.image=[arr objectAtIndex:1];
imagestr=#"1";
break;
case 1:
_imaging.image=[arr objectAtIndex:2];
imagestr=#"2";
break;
case 2:
_imaging.image=[arr objectAtIndex:3];
imagestr=#"3";
break;
case 3:
_imaging.image=[arr objectAtIndex:4];
imagestr=#"4";
break;
case 4:
_imaging.image=[arr objectAtIndex:0];
imagestr=#"0";
break;
default:
break;
}
}
On clicked on next button
Before using this first set currentIndex in this
-(IBAction)next{
if (arr.count > 0) {
currentIndex++;
if (currentIndex > arr.count - 1) {
currentIndex = 0;
}
imageViewObj.image = [arr objectAtIndex:currentIndex];
}
}
on pervious button
-(IBAction)pervious{
if (arr.count > 0) {
currentIndex--;
if (currentIndex <= 0) {
currentIndex = arr.count - 1;
}
imageViewObj.image = [arr objectAtIndex:currentIndex];
}
}
Try this is working fine
Set some integer property currentIndex to 2 (if you load first the 3rd image).
When calling the next/previous methods increment/decrement that property and load the correct image. ImageView *image = [arr objectAtIndex:currentIndex]
when you initialize your view controller, keep track of the current image being viewed for example 0, to be used as an array index.
When next is pressed, increment the index and retrieve the image from the array using the updated count.
e.g.
- (IBAction)next:(id)sender {
imageCount++;
[myImageView setImage:[UIImage imageNamed:arr[imageCount] ];
}
hope this helps. :)

4 random function in specific interval time

I have 4 function and i want to execute them randomly every 1 second for unlimited time.
This is my code to execute a random function:
-(void) Game
{
int rand = arc4random() % 5;
switch (rand) {
case 0:
[self appearred];
break;
case 1:
[self appearblue];
break;
case 2:
[self appearyellow];
break;
case 3:
[self appeargreen];
break;
}
}
But how can i repeat this function every 1 second??
You can also try like this
*
-(void) Game
{
int rand = (int)arc4random() % 4;
switch (rand) {
case 0:
[self appearred];
break;
case 1:
[self appearblue];
break;
case 2:
[self appearyellow];
break;
case 3:
[self appeargreen];
break;
}
[self performSelector:#selector(Game) withObject:nil afterDelay:1.0];
}
*
It will call the Game Functions after each second
Just use a NSTimer.
PS : You will not be 100% sure that this will append every 1second.
Use below code which will call Game method every 1.0 second. One more thing, in your Game method you need to use % 4 instead of % 5 to get value between 0 to 3.
[NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(Game)
userInfo:nil
repeats:YES];
-(void) Game
{
int rand = (int)arc4random() % 4;
switch (rand) {
case 0:
[self appearred];
break;
case 1:
[self appearblue];
break;
case 2:
[self appearyellow];
break;
case 3:
[self appeargreen];
break;
}
}

Resources