looping or global variable or passing variables - ios

This is a tough question. I will simply state what my program can do at the moment. Simply it is a top up system
shows the current balance (eg. $26.00)
I can select a top up value from segmented control (eg. top up $20)
current balance will be updated after selecting a top up. (current balance = $46)
Now here's the problem - when I try to top up again it should add on top of the amount shown but it starts over from scratch and tops up the initial set value.
I was hoping theres a method of saving it as a global variable or even pass it from a method or loop until program has ended.
this is the .m file
// button for confirming the selected top up amount & confirmation box
- (IBAction) confirmAmount:(id)sender{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Confirm Payment" message:#"Would you like to proceed with the payment?" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Yes", nil];
alertView.tag = 108;
[alertView show];
}
// method for toping up different amounts with segmentedcontrol
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
result =26.00;
for (int i = 0; i < 100; i++){
if (topUpamount.selectedSegmentIndex == 0)
{
result = result+ 20;
}
else if (topUpamount.selectedSegmentIndex == 1)
{
result = result + 40;
}
else if (topUpamount.selectedSegmentIndex == 2)
{
result = result + 50;
}
else if (topUpamount.selectedSegmentIndex == 3)
{
result = result + 60;
}
else if (topUpamount.selectedSegmentIndex == 4)
{
result = result + 80;
}
else
{
result = 0;
}
if (alertView.tag==108)
{
switch (buttonIndex) {
case 0:
break;
case 1:
currentBalance.text = [[NSString alloc] initWithFormat: #"%.2f",result]; break;
default:
break;
}
}

Related

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;
}

getting the contents of UIButton press

I'm not sure if this has been asked before, but I'm gonna ask anyways. I am working on a grid of buttons, with letters as the titles of each one. I am getting the contents of these letters from an array, and I believe that is where my issue is coming from. The titles appear just fine, but when I press on any of the buttons in my array, that is where my issue comes in.
Every time I press a letter, the part of my NSLog NSLog(#"Letter Added to Array: %#", self.sectionButton.titleLabel.text);
displays
Letter Added to Array: S
and that is all that is displayed. No matter what button is pushed. I am thinking it might just be because of S being the last object in my array, which is why it's saying that. I don't know, so ANY help would be appreciated.
Here is my code:
- (void) didTouchButton
{
[self.lettersPressedArray addObject:self.sectionButton.titleLabel.text];
NSLog(#"Letter Added to Array: %#", self.sectionButton.titleLabel.text);
NSLog(#"Letters Pressed = %#", self.lettersPressedArray);
}
- (void)showGridWithRows:(int)r columns:(int)c arrayOfContent:(NSArray *)content withSizeOfContent:(CGFloat)contentSize
{
for (int i = 0; i < content.count; i++) {
// vars
int row = (int)i / r; // to figure out the rows
int col = i % c; // to figure out the columns
float x = 0;
float y = 0;
// sizing options
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
CGSize screen = [UIScreen mainScreen].bounds.size;
if (screen.height == 480) {
x = 1 + (40 * col);
y = 1 + (30 * row);
}
else {
x = 2 + (40 * col);
y = 1 + (31 * row);
}
}
else {
x = .5 + (90 * col);
y = 1 + (90 * row);
}
//button
self.sectionButton = [UIButton buttonWithType:UIButtonTypeSystem];
[self.sectionButton setTintColor:[UIColor lightGrayColor]];
self.sectionButton.frame = CGRectMake(x, y, contentSize, contentSize);
self.sectionButton.tag = 100 + row * c + col;
[self.sectionButton addTarget:self action:#selector(didTouchButton) forControlEvents:UIControlEventTouchUpInside];
// font stuff
self.sectionButton.titleLabel.textAlignment = NSTextAlignmentCenter;
self.sectionButton.titleLabel.backgroundColor = [UIColor clearColor];
self.sectionButton.titleLabel.font = [UIFont fontWithName:#"Helvetica-Light" size:22];
[self.sectionButton setTitleColor:[UIColor blackColor]/*[UIColor colorWithRed:241.0/255.0 green:124.0/255.0 blue:22.0/255.0 alpha:1.0]*/ forState:UIControlStateNormal];
// title
s = (NSString *)[content objectAtIndex:i];
[self.sectionButton setTitle:s forState:UIControlStateNormal];
// color
if ([s isEqualToString:#"A"] ) {
[self.sectionButton setBackgroundColor:[UIColor greenColor]];
}
else if([s isEqualToString:#"Z"]) {
[self.sectionButton setBackgroundColor:[UIColor redColor]];
}
else {
[self.sectionButton setBackgroundColor:[UIColor lightGrayColor]];
}
//layer
self.sectionButton.layer.borderWidth = .65;
//self.sectionButton.layer.cornerRadius = 5.0;
for(int j = 0; j < c; j++) {
for (int k = 0; k < r; k++) {
[self addSubview:self.sectionButton];
}
}
}
}
Change this:
- (void) didTouchButton
{
[self.lettersPressedArray addObject:self.sectionButton.titleLabel.text];
NSLog(#"Letter Added to Array: %#", self.sectionButton.titleLabel.text);
NSLog(#"Letters Pressed = %#", self.lettersPressedArray);
}
To this:
- (void) didTouchButton:(UIButton *)sender
{
[self.lettersPressedArray addObject:sender.titleLabel.text];
NSLog(#"Letter Added to Array: %#", sender.titleLabel.text);
NSLog(#"Letters Pressed = %#", self.lettersPressedArray);
}
And when you assign your button selector add a ':'
So, this:
#selector(didTouchButton)
Will be:
#selector(didTouchButton:)
Probably implemented like:
[someButton addTarget:self action:#selector(didTouchButton:) forControlEvents:UIControlEventTouchUpInside];
Because:
The way you originally reference your button via self.selectionButton.titleLabel.text accesses one specific instance of a button. This means that no matter what button triggers didTouchButton it gets the content of self.selectionButton which I'm assuming displays an "S". This means that no matter what happens, you add more of the letter "S" to your array. By configuring our action method like we did, it will pass "self" as an argument. This means that we have a variable representing whoever called the method within the method. We will use that to get our contents and add them to the array.
Couple things here. Firstly, you likely don't want to have the button be a property, because you are constantly overwriting it and are ultimately left with it referencing the last one you created... What you're basically doing is the same as:
int x = 1;
x = 2;
x = 3;
printing x will ALWAYS result in 3... Make sense?
The solution to your problem is to pass the button you are tapping as a parameter to the function that handles the action, by adding in a ":" after "didTouchButton" and changing the way you create that function. When you create the button, add the : after the function name like this:
[button addTarget:self action:#selector(didTouchButton:) forControlEvents:UIControlEventTouchUpInside];
That allows a reference to the button pressed to be passed to the function, so you can do this to handle it:
- (void)didTouchButton:(UIButton *)button {
NSString *titleOfPressedButton = button.titleLabel.text;
}
You need to change didTouchButton method to accept (id)sender parameter and change how you set up it's selector while creating a button to didTouchButton:.
This way you will receive a button object pointer inside the didTouchButton and will be able to get its information.

Sorting views in a grid after a view is moved via gesture to a new position

This is turing into a bit of a brain buster, but I assume there is a very simple and efficient method to do this.
In my app I have views laid out in a grid. Views can be moved to any location via gesture. The problem is making the view sort to just the right location after the gesture event. Basically I am doing this. Works sort of but not correct yet.
Note: the tag of the views will always update to the current position of the view in the grid.
Below is the code I am using to sort, and here is a link to the actual project in a zip file.
-(void)sortViews:(UIView*)myView {
__block int newIndex;
// myView is the view that was moved.
[viewsArray removeObject:myView];
[viewsArray enumerateObjectsUsingBlock:^(UIView *view, NSUInteger idx, BOOL *stop){
if (myView.center.x > view.center.x) {
if (myView.center.y > view.center.y) {
newIndex = view.tag -1;
*stop = YES;
} else {
newIndex = view.tag +1;
*stop = YES;
}
} else if (myView.center.x < view.center.x) {
if (myView.center.y > view.center.y) {
newIndex = view.tag -1;
*stop = YES;
} else {
newIndex = view.tag +1;
*stop = YES;
}
}
}];
if (newIndex < 0) {
newIndex = 0;
} else if (newIndex > 5) {
newIndex = 5;
}
[viewsArray insertObject:myView atIndex:newIndex];
[UIView animateWithDuration:.4 animations:^{
[self arrangeGrid];
}];
}
You can store the original positions of all the views in an array (lets say positionArray), and then when you are moving a view "A" just go on checking the current position of view "A" with the stored positions in the positionArray, if a view is in range of any stored location just swap the position of view "A" with the view in whose range view "A" has come.
Hope this will help you
Found an easier solution that seems to work just fine. I replace the code within the viewsArray enumeration with this:
if (CGRectContainsPoint(view.frame, myView.center)) {
newIndex = view.tag;
*stop = YES;
}

How change value of segmentedcontrol by swipegesture?

How change value of segmentedcontrol by swipegesture?
"Invalid parameter not satisfying: selectedSegmentIndex < (NSInteger)self._items.count"
- (void)updateSelectedSegmentText
{
int theSegmentIndex = [_segmentedControl selectedSegmentIndex];
NSDictionary *theInfo = [self.top.segments objectAtIndex:theSegmentIndex];
self.bioTextView.text = [NSString stringWithFormat:#"%#", theInfo [#"sData"]];
[self.bioTextView scrollRangeToVisible:NSMakeRange(0, 0)];
}
- (void)swipe:(UISwipeGestureRecognizer *)swipeRecogniser
{
s = 1;
if ([swipeRecogniser direction] == UISwipeGestureRecognizerDirectionLeft)
{
self.segmentedControl.selectedSegmentIndex -=s;
[self updateSelectedSegmentText];
}
else if ([swipeRecogniser direction] == UISwipeGestureRecognizerDirectionRight)
{
self.segmentedControl.selectedSegmentIndex +=s;
[self updateSelectedSegmentText];
}
}
You need to first check if the new index is valid. You cannot go to the left if you are already on the first tab and you cannot go to the right if you are on the last tab. So you need to first calculate the new index and then check if it is in range before you set the selectedSegmentIndex property:
NSInteger index = self.segmentedControl.selectedSegmentIndex;
if ([swipeRecogniser direction] == UISwipeGestureRecognizerDirectionLeft) {
--index;
} else if ([swipeRecogniser direction] == UISwipeGestureRecognizerDirectionRight) {
++index;
}
if (0 <= index && index < self.segmentedControl.numberOfSegments) {
self.segmentedControl.selectedSegmentIndex = index;
[self updateSelectedSegmentText];
}

transform image when it hits the edge of the screen in iOS

I have 10 fireflies that I make "fly" around the screen using the code below.
The code also serves to keep the fireflies on the screen.
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *blueArray = [NSArray array];
blueArray = [[NSArray alloc] initWithObjects:
[UIImage imageNamed:#"blue1.png"],
[UIImage imageNamed:#"blue2.png"], nil];
blue.animationImages = blueArray;
blue.animationDuration = 0.20;
blue.animationRepeatCount = -1;
[blue startAnimating];
bluepos =CGPointMake(2.0, 1.5);
}
-(void) someMethod {
endingAnimationTimer = [NSTimer scheduledTimerWithTimeInterval:(0.03) target:self selector:#selector(makeFly) userInfo:nil repeats:YES];
}
-(void) makeFly {
blue.center = CGPointMake(blue.center.x+bluepos.x, blue.center.y+bluepos.y);{
if(blue.center.x > 480 || blue.center.x <0)
bluepos.x = -bluepos.x;
if(blue.center.y > 320 || blue.center.y <0)
bluepos.y = -bluepos.y;
}
}
The "flying" works great except that when the fireflies hit the edge of the screen and reverse direction to keep them on the screen the firefly image itself is still "facing" the othe direction so it looks like they are flying backwards half the time.
I want to set it up so that when the fireflies hit the edge of the screen they reverse direction AND the image itself is reversed.
I tried this:
In .h
#property (nonatomic, assign) BOOL blueIsFacingRight;
In .m
#synthesize blueIsFacingRight;
-(void) makeFly {
blue.center = CGPointMake(blue.center.x+bluepos.x, blue.center.y+bluepos.y); {
if(blue.center.x > 480 ) {
if (blueIsFacingRight == YES) {
blue.transform = CGAffineTransformMakeScale(-1, 1);
blueIsFacingRight = NO;
}
bluepos.x = -bluepos.x;
}
if(blue.center.x <0) {
bluepos.x = -bluepos.x;
if (blueIsFacingRight == NO) {
blue.transform = CGAffineTransformMakeScale(1, 1);
blueIsFacingRight = YES;
}
}
if(blue.center.y > 320 )
bluepos.y = -bluepos.y;
if( blue.center.y <0)
bluepos.y = -bluepos.y;
}
}
I thought this would work but the image does not reverse when it hits the "wall"
Can anyone explain why this does not work and if there is a better why to accomplish the effect im looking for?
You are setting the transform X value to -1 in both cases. When its facing right you should set transform like this CGAffineTransformMakeScale(1, 1);
blue.center = CGPointMake(blue.center.x+bluepos.x, blue.center.y+bluepos.y); {
if(blue.center.x > 480 ) {
if (blueIsFacingRight == YES) {
blue.transform = CGAffineTransformMakeScale(-1, 1);
blueIsFacingRight = NO;
}
bluepos.x = -bluepos.x;
}
if(blue.center.x <0) {
bluepos.x = -bluepos.x;
if (blueIsFacingRight == NO) {
blue.transform = CGAffineTransformMakeScale(1, 1);
blueIsFacingRight = YES;
}
}
**blue.transform =CGAffineTransformIdentity;**
THe above was in my makeFly method with a bunch of other stuff above where I was reversing the image so I was undoing the change the very next time the method was called ( 0.03 later)
Man I feel stupid

Resources