Using Gestures with Switch Case (iOS) - ios

I am new to creating apps for the iOS. Recently, I've been working on making a calculator app based on gestures. I am using switch cases to change operations, and I originally had it rigged up with buttons, but now I want to use gestures. Here is my code so far. The opAddition function is the first way I tried it, but it wouldn't switch functions. For example, if I wanted to switch from addition to subtraction, it would only work after the number was inputed. That's why I tried to use Switch-Case, but now I don't know how to link up gestures to them.
#implementation ABViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
calculatorScreen.adjustsFontSizeToFitWidth = YES;
self.notification.layer.cornerRadius = 90;
self.notification.layer.masksToBounds = YES;
self.notification.alpha = 0;
[[self.notification layer] setBorderWidth:8.0f];
[[self.notification layer] setBorderColor:[UIColor whiteColor].CGColor];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - buttons
-(IBAction)buttonDigitPressed:(id)sender{
currentNumber = currentNumber *10 + (int)[sender tag];
NSString *number = [NSString stringWithFormat:#"%.1f", currentNumber];
if ( number.length < 11) {
calculatorScreen.text = number;
}
};
#pragma mark - operator button code
-(IBAction)buttonOperationPressed:(id)sender{
if (currentOperation == 0) { result = currentOperation; }
else {
if (_operationSimple.direction == UISwipeGestureRecognizerDirectionUp){
currentOperation = 1;
} else if (_operationSimple.direction == UISwipeGestureRecognizerDirectionDown){
currentOperation = 2;
}
switch (currentOperation) {
case 1:
result = result + currentNumber;
self.notificationText.text = #"+";
[self notify];
break;
case 2:
result = result - currentNumber;
self.notificationText.text = #"-";
[self notify];
break;
case 3:
result = result * currentNumber;
break;
case 4:
result = result / currentNumber;
break;
case 5:
currentOperation = 0;
break;
}
}
currentNumber = 0;
calculatorScreen.text = [NSString stringWithFormat:#"%.1f", result];
if ( [sender tag] == 0) { result = 0; }
currentNumber = [sender tag];
};
#pragma mark - Cancelations
-(IBAction)cancelInput{
currentNumber = 0;
self.notificationText.text = #"C";
[self notify];
calculatorScreen.text = #"0.0";
result = 0.0;
NSLog(#"Cancel Input");
}
-(IBAction)cancelOperation{
currentNumber = 0;
self.notificationText.text = #"AC";
[self notify];
calculatorScreen.text = #"0.0";
currentOperation = 0;
NSLog(#"Clear Operation");
}
double newresult = 0;
#pragma mark - Operations
-(IBAction)opAddition{
result = result + currentNumber;
self.notificationText.text = #"+";
[self notify];
newresult = result;
currentNumber = 0;
NSLog(#"Number Added. New result:");
NSLog([NSString stringWithFormat:#"%2f", newresult]);
calculatorScreen.text = [NSString stringWithFormat:#"%.1f", result];
}
#pragma mark - notification stuffs
- (void)notify{
[UIView animateWithDuration:1.0 animations:^{
self.notification.alpha = 1.0f;
}];
[UIView animateWithDuration:1.0 animations:^{
self.notification.alpha = 0.0f;
}];
}
#end

Related

how to get the uibutton state value in test.m file

In .m file i have methods like
-(void) textdata
{
long i = search.text.length;
if (i > 0) {
searchButton.enabled = YES;
}
else
{
searchButton.enabled = NO;
}
[self buttonstate];
}
-(int) buttonstate
{
if ([searchButton isEnabled]) {
j = 1;
}
else
j = 0;
NSLog(#" j value is %d",j);
return j;
}
- (void) textFieldDidChange
{
[self textdata];
NSLog(#"test data is %#",search.text);
}
And in the tests.m file i have test like
-(void) testwithoutData
{
myapiViewController *apiViw = [[myapiViewController alloc]init];
[apiViw textdata];
int kn = [apiViw buttonstate];
NSLog(#"the value is %ld",(long)kn);
}
You have to do alloc init because due to this instance variable getting nil. Try this -
In ViewController.m -
-(int) buttonstate {
long i = self.searchTxt.text.length;
if (i > 0) {
self.searchBtn.enabled = YES;
}
else
{
self.searchBtn.enabled = NO;
}
if ([self.searchBtn isEnabled]) {
j = 1;
}
else
j = 0;
NSLog(#" j value is %d",j);
return j;
}
In ViewControllerTests.m -
- (void)testExample {
// This is an example of a functional test case.
XCTAssert(YES, #"Pass");
self.vcToTest.searchTxt = [[UITextField alloc] init];
self.vcToTest.searchBtn = [[UIButton alloc] init];
self.vcToTest.searchTxt.text = #"test";
int kn = [self.vcToTest buttonstate];
NSLog(#"the value is %ld",(long)kn);
}
Check the attached screenshot output -

NodesAtPoint does not find a node

I'm trying to create 10 balloons in my app. I create a random CGPoint to set my node's position and check, in case that already exist a node at this point I try again.
I don't know why, the balloons keep being placed over another balloon.
Any ideia of what I am doing wrong?
Here is my code:
-(void)gerarBaloes:(int)quantidade
{
balloons = [NSMutableArray new];
u_int32_t maxHorizontal = 900;
u_int32_t minHorizontal = 100;
u_int32_t maxVertical = 650;
u_int32_t minVertical = 100;
for (int i=1; i<= quantidade; i++) {
CGPoint posicao = CGPointMake(arc4random_uniform(maxHorizontal - minHorizontal + 1) + minHorizontal, arc4random_uniform(maxVertical - minVertical + 1) + minVertical);
while (![self validPosition:posicao]) {
posicao = CGPointMake(arc4random_uniform(maxHorizontal - minHorizontal + 1) + minHorizontal, arc4random_uniform(maxVertical - minVertical + 1) + minVertical);
}
balao* nBalao = [[balao alloc]initWithPosition:posicao];
SKLabelNode* numero = [[SKLabelNode alloc]initWithFontNamed:#"Arial Rounded MT Bold"];
numero.text = [NSString stringWithFormat:#"%d",i];
numero.zPosition = 1;
nBalao.body.zPosition = 0;
[nBalao addChild:numero];
nBalao.body.name = #"balloon";
[balloons addObject:nBalao];
[self addChild:nBalao];
}
}
And this is my validation method:
-(BOOL)validPosition:(CGPoint)position
{
NSArray* nodes = [self nodesAtPoint:position];
NSLog(#"total de nodes %d",nodes.count);
if (nodes.count > 0) {
for (SKNode* n in nodes) {
if ([n isKindOfClass:[balao class]]) {
return NO;
}
}
return YES;
}else{
return YES;
}
}
Balao.m class:
#implementation balao
-(id)initWithPosition:(CGPoint)pos
{
if (self = [super init]) {
self.position = pos;
int n = arc4random_uniform(4);
_balloonAtlas = [SKTextureAtlas atlasNamed:[NSString stringWithFormat:#"balloon%d",n]];
_explosionFrames = [NSMutableArray array];
int numImages = _balloonAtlas.textureNames.count;
for (int i=1; i<= numImages; i++){
NSString *textureName = [NSString stringWithFormat:#"balloon_%d",i];
SKTexture *temp = [_balloonAtlas textureNamed:textureName];
[_explosionFrames addObject:temp];
}
SKTexture *textInicial = [_explosionFrames[0] copy];
[_explosionFrames removeObjectAtIndex:0];
self.body = [SKSpriteNode spriteNodeWithTexture:textInicial];
[self addChild:_body];
}
return self;
}
- (void)explodeBalloon
{
SKAction* explosao = [SKAction animateWithTextures:_explosionFrames timePerFrame:0.02f resize:NO restore:YES];
[self.body runAction:explosao completion:^(void){
[self removeFromParent];
}];
[self runAction:[SKAction playSoundFileNamed:#"popSound.mp3" waitForCompletion:NO]];
}
This is how the balloons appears:
Edit:
I tried the suggested method, with CGRectCointainsPoint, but it didn't work too. :/
Checking for nodes at a given point is not enough to prevent overlap. You need to check whether the point falls inside the frame of another balloon. You can modify the function like this
-(BOOL)validPosition:(CGPoint)position
{
NSArray* nodes = [self children];
if (nodes.count > 0) {
for (SKNode* n in nodes) {
if ([n isKindOfClass:[balao class]]) {
if (CGRectContainsPoint([n getBalloonFrame], position)) // Changed line
{
return NO
}
}
}
return YES;
}
return YES;
}
CGRectContainsPoint checks whether a given rectangle contains a point.
Inside balao class define the following function. Also note the changed line in the above code.
-(void)getBalloonFrame
{
return CGRectOffset(self.body.frame, self.frame.origin.x, self.frame.origin.y)
}

Expected identifier on if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)

*This is the whole code :)
I have been trying to fix this for an hour now, but i can still not make it.
I would be happy if someone could help me :)
Still can't make the UI_USER_INTERFACE_IDIOM code work.*
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
-(void)Collision{
if (CGRectIntersectsRect(Heli.frame, Obstacle.frame)) {
[self EndGame];
}
if (CGRectIntersectsRect(Heli.frame, Obstacle2.frame)) {
[self EndGame];
}
if (CGRectIntersectsRect(Heli.frame, Bottom1.frame)) {
[self EndGame];
}
if (CGRectIntersectsRect(Heli.frame, Top1.frame)) {
[self EndGame];
}
}
-(void)EndGame{
if (Scorenumber > HighScore) {
HighScore = Scorenumber;
[[NSUserDefaults standardUserDefaults] setInteger:HighScore
forKey:#"HighScoreSaved"];
}
Heli.hidden = YES;
[timer invalidate];
[Scorer invalidate];
[self performSelector:#selector(NewGame) withObject: nil afterDelay:2];
}
-(void)NewGame{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
// For iPhone
Bottom1.hidden = YES;
Top1.hidden = YES;
Obstacle.hidden = YES;
Obstacle2.hidden = YES;
corona.hidden = YES;
Intro1.hidden = NO;
Intro2.hidden = NO;
Intro3.hidden = NO;
Heli.hidden = NO;
Heli.center = CGPointMake(88, 286);
Heli.image = [UIImage imageNamed:#"buss til app opp.png"];
Start = YES;
Scorenumber = 0;
Score.text = [NSString stringWithFormat:#"Score: 0"];
Intro3.text = [NSString stringWithFormat:#"HighScore: %i", HighScore];
}
} else{
// For iPad
Bottom1.hidden = YES;
Top1.hidden = YES;
Obstacle.hidden = YES;
Obstacle2.hidden = YES;
corona.hidden = YES;
Intro1.hidden = NO;
Intro2.hidden = NO;
Intro3.hidden = NO;
Heli.hidden = NO;
Heli.center = CGPointMake(153, 515);
Heli.image = [UIImage imageNamed:#"buss til app opp.png"];
Start = YES;
Scorenumber = 0;
Score.text = [NSString stringWithFormat:#"Score: 0"];
Intro3.text = [NSString stringWithFormat:#"HighScore: %i", HighScore];
Just look at following code:
-(void)NewGame{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
// For iPhone
Bottom1.hidden = YES;
Top1.hidden = YES;
Obstacle.hidden = YES;
Obstacle2.hidden = YES;
corona.hidden = YES;
Intro1.hidden = NO;
Intro2.hidden = NO;
Intro3.hidden = NO;
Heli.hidden = NO;
Heli.center = CGPointMake(88, 286);
Heli.image = [UIImage imageNamed:#"buss til app opp.png"];
Start = YES;
Scorenumber = 0;
Score.text = [NSString stringWithFormat:#"Score: 0"];
Intro3.text = [NSString stringWithFormat:#"HighScore: %i", HighScore];
}
} else{
and see - "}" symbol on line before "} else{" is wrong. It is the pair for
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
opening construction, so "else" is "standalone - it is wrong.
Try to delete this "}".

Tap gesture causes strange behavior

I’m building a reaction test that requires the user to tap on the target dot, while other non-target dots come down. It works most of the time but sometimes after tapping on a target dot it will display several other dots with weird behavior. I’ve been looking at the code for days and I can’t find the problem. Does anyone have any suggestions?
Thanks much. Here’s the code.
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// single tap gesture recognizer
self.myTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(theTap:)];
self.myTap.numberOfTapsRequired = 1;
[self.firstView addGestureRecognizer:self.myTap];
self.myTap.enabled = NO;
self.colorToHit = self.colorFromPreviousController;
[self KickOff];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.holdTheReactionTimes = [[NSMutableArray alloc] initWithCapacity:50];
self.firstTime = YES;
numberOfTries = 0;
}
#pragma mark - Utility Methods
- (void)setRandomLocationForView:(UIView *)view
{
CGRect sinkBounds = CGRectInset(self.firstView.bounds, view.frame.size.width/2, view.frame.size.height/2);
CGFloat x = arc4random() % (int)sinkBounds.size.width + view.frame.size.width/2;
CGFloat y = arc4random() % (int)sinkBounds.size.height + view.frame.size.height/2;
view.center = CGPointMake(x, y);
}
- (void)addLabel
{
[self stopDraining];
static NSArray *buttons = nil;
buttons = [[NSArray alloc] initWithObjects:
#"XX.png",
#"YY.png",
#"ZZ.png",
nil];
int theIndex = arc4random()%[buttons count];
NSLog(#"the index: %d", theIndex);
NSString *theImageName = [buttons objectAtIndex:theIndex];
CGRect anotherFrame = CGRectMake(10, 10, 64, 64);
UIView *anotherView = [[UIView alloc] initWithFrame:anotherFrame]
UIImageView *imageView1 = [[UIImageView alloc] initWithFrame:CGRectMake(-2, -2, 64, 64)];
imageView1.image = [UIImage imageNamed:theImageName];
[anotherView addSubview:imageView1];
[self setRandomLocationForView:anotherView];
[self.firstView addSubview:anotherView];
NSDate *date = [NSDate date];
timeOne = [date timeIntervalSince1970];
if (theIndex == self.colorToHit) {
NSLog(#"the right color");
self.isThisTheRightColor = YES;
self.myTap.enabled = YES;
numberOfTries += 1;
} else {
NSLog(#"the wrong color");
self.isThisTheRightColor = NO;
self.myTap.enabled = NO;
[self startDraining];
}
}
#pragma mark - View Animation
#define ANIMATE_DURATION 6.0
#define SLEEP_INTERVAL 0.5
- (void)theTap:(UITapGestureRecognizer *)gesture
{
NSLog(#"Tapped");
float tapInterval = 0;
CGPoint tapLocation = [gesture locationInView:self.firstView];
for (UIView *view in self.firstView.subviews) {
if (CGRectContainsPoint(view.frame, tapLocation)) {
NSLog(#"we hit one");
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate); // added this 4-27
if (self.firstTime) {
NSDate *date = [NSDate date];
timeTwo = [date timeIntervalSince1970];
NSLog(#"TAP First time: %f", timeTwo);
self.firstTime = NO;
} else {
NSDate *date = [NSDate date];
timeTwo = [date timeIntervalSince1970];
NSLog(#"Second time: %f", timeTwo);
}
tapInterval = (timeTwo - timeOne);
NSLog(#"Time Interval: %f", tapInterval);
[view removeFromSuperview];
[self writeTimeStampToArray:tapInterval];
}
}
}
- (void)KickOff
{
for (UIView *view in self.firstView.subviews) {
[view removeFromSuperview];
}
if (self.firstView.window) {
[self addLabel];
}
}
- (void)writeTimeStampToArray:(float)timeStamp
{
NSNumber *timeObject = [NSNumber numberWithFloat: timeStamp];
[self.holdTheReactionTimes addObject:timeObject];
if (numberOfTries < NUMBER_OF_TRIES) {
[self addLabel];
} else {
[self nextScreen];
}
}
- (void)nextScreen
{
[self performSegueWithIdentifier: #"viewsummary" sender: self];
}
}
}
#pragma mark - Flipside View
- (void)ReactionViewControllerDidFinish:(int)trynumber
{
self.tryNumberInt = trynumber;
[self dismissViewControllerAnimated:YES completion:nil];
}
#define COUNTER 4
//////////////
// drain logic
- (void)drain:(NSTimer *)timer
{
[self drain];
}
#define DRAIN_DURATION 2.0
- (void)startDraining
{
self.drainTimer = [NSTimer scheduledTimerWithTimeInterval:DRAIN_DURATION/3
target:self
selector:#selector(drain:)
userInfo:nil
repeats:YES];
}
- (void)stopDraining
{
[self.drainTimer invalidate];
}
- (void)drain
{
for (UIView *view in self.firstView.subviews) {
CGAffineTransform transform = view.transform;
if (CGAffineTransformIsIdentity(transform)) {
UIViewAnimationOptions options = UIViewAnimationOptionCurveLinear;
[UIView animateWithDuration:DRAIN_DURATION/3 delay:0 options:options animations:^{
view.transform = CGAffineTransformRotate(CGAffineTransformScale(transform, 0.7, 0.7), 2*M_PI/3);
} completion:^(BOOL finished) {
if (finished) {
[UIView animateWithDuration:DRAIN_DURATION/3 delay:0 options:options animations:^{
view.transform = CGAffineTransformRotate(CGAffineTransformScale(transform, 0.4, 0.4), -2*M_PI/3);
} completion:^(BOOL finished) {
if (finished) {
[UIView animateWithDuration:DRAIN_DURATION/3 delay:0 options:options animations:^{
view.transform = CGAffineTransformScale(transform, 0.1, 0.1);
} completion:^(BOOL finished) {
if (finished) [view removeFromSuperview];
}];
}
}];
}
}];
}
}
[self addLabel];
}

Problems with view controllers going into the background of UITabBarController

I have a UITabBarController with 3 view controllers connected to it. Everything works fine apart from when you switch from one view to another, the new view takes a moment to reload what it was doing. I know this isn't such a big deal but it just makes the app look a bit sloppy. Does anyone know how I can keep the app running in the background, or something so that it doesn't have to reload each time.
As you might have noticed I'm very new to Objective-C so I can understand if I'm being unclear but any help is really appreciated!
EDIT: FOR DAVID
This is the code for the stopwatch in the .m file:
#implementation StopwatchViewController
- (BOOL)prefersStatusBarHidden
{
return YES;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
isCounting = false;
}
- (IBAction)startOrStop:(id)sender
{
if (self->isCounting == false) {
self->isCounting = true;
[self startStopwatch];
} else {
self->isCounting = false;
[self stopStopwatch];
}
}
- (void)startStopwatch
{
[startStopButton setTitle:#"STOP" forState:UIControlStateNormal];
[self performSelector:#selector(stopwatch) withObject:self afterDelay:1.0];
}
- (IBAction)resetStopwatch:(id)sender
{
[self reset];
}
- (void)stopwatch
{
if (self->isCounting == false) {
return;
} else {
NSInteger hourInt = [hourLabel.text intValue];
NSInteger minuteInt = [minuteLabel.text intValue];
NSInteger secondInt = [secondLabel.text intValue];
if (secondInt == 59) {
secondInt = 0;
if (minuteInt == 59) {
minuteInt = 0;
if (hourInt == 23) {
hourInt = 0;
} else {
hourInt += 1;
}
} else {
minuteInt += 1;
}
} else {
secondInt += 1;
}
NSString *hourString = [NSString stringWithFormat:#"%02d", hourInt];
NSString *minuteString = [NSString stringWithFormat:#"%02d", minuteInt];
NSString *secondString = [NSString stringWithFormat:#"%02d", secondInt];
hourLabel.text = hourString;
minuteLabel.text = minuteString;
secondLabel.text = secondString;
CGRect hourFrame = self->hourBar.frame;
CGRect minuteFrame = self->minuteBar.frame;
CGRect secondFrame = self->secondBar.frame;
if ((NSInteger)hourFrame.size.height != hourInt) { // check if we need to modify
hourFrame.origin.y -= ((hourInt * 10.0) - hourFrame.size.height);
hourFrame.size.height = (hourInt * 10.0);
self->hourBar.frame = hourFrame;
}
if ((NSInteger)minuteFrame.size.height != minuteInt) { // check if we need to modify
minuteFrame.origin.y -= ((minuteInt * 4.0) - minuteFrame.size.height);
minuteFrame.size.height = (minuteInt * 4.0);
self->minuteBar.frame = minuteFrame;
}
if ((NSInteger)secondFrame.size.height != secondInt) { // check if we need to modify
secondFrame.origin.y -= ((secondInt * 4.0) - secondFrame.size.height);
secondFrame.size.height = (secondInt * 4.0);
self->secondBar.frame = secondFrame;
}
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(stopwatch) userInfo:nil repeats:NO];
}
}
- (void)stopStopwatch
{
[startStopButton setTitle:#"START" forState:UIControlStateNormal];
}
- (void)reset
{
[startStopButton setTitle:#"START" forState:UIControlStateNormal];
self->isCounting = false;
hourLabel.text = #"00";
minuteLabel.text = #"00";
secondLabel.text = #"00";
CGRect hourFrame = self->hourBar.frame;
CGRect minuteFrame = self->minuteBar.frame;
CGRect secondFrame = self->secondBar.frame;
hourFrame.size.height = 0;
minuteFrame.size.height = 0;
secondFrame.size.height = 0;
hourFrame.origin.y = 321.0;
minuteFrame.origin.y = 321.0;
secondFrame.origin.y = 321.0;
self->hourBar.frame = hourFrame;
self->minuteBar.frame = minuteFrame;
self->secondBar.frame = secondFrame;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
SECOND EDIT FOR DAVID:
Changed the main parts of the code to look like this:
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:YES];
[self swapFrames];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
[self updateBars];
}
- (void)stopwatch
{
if (self->isCounting == false) {
return;
} else {
hourInt = [hourLabel.text intValue];
minuteInt = [minuteLabel.text intValue];
secondInt = [secondLabel.text intValue];
if (secondInt == 59) {
secondInt = 0;
if (minuteInt == 59) {
minuteInt = 0;
if (hourInt == 23) {
hourInt = 0;
} else {
hourInt += 1;
}
} else {
minuteInt += 1;
}
} else {
secondInt += 1;
}
NSString *hourString = [NSString stringWithFormat:#"%02d", hourInt];
NSString *minuteString = [NSString stringWithFormat:#"%02d", minuteInt];
NSString *secondString = [NSString stringWithFormat:#"%02d", secondInt];
hourLabel.text = hourString;
minuteLabel.text = minuteString;
secondLabel.text = secondString;
[self swapFrames];
[self updateBars];
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(stopwatch) userInfo:nil repeats:NO];
}
}
- (void)updateBars
{
if ((NSInteger)hourFrame.size.height != hourInt) { // check if we need to modify
hourFrame.origin.y -= ((hourInt * 10.0) - hourFrame.size.height);
hourFrame.size.height = (hourInt * 10.0);
self->hourBar.frame = hourFrame;
}
if ((NSInteger)minuteFrame.size.height != minuteInt) { // check if we need to modify
minuteFrame.origin.y -= ((minuteInt * 4.0) - minuteFrame.size.height);
minuteFrame.size.height = (minuteInt * 4.0);
self->minuteBar.frame = minuteFrame;
}
if ((NSInteger)secondFrame.size.height != (secondInt * 4.0)) { // check if we need to modify
secondFrame.origin.y -= ((secondInt * 4.0) - secondFrame.size.height);
secondFrame.size.height = (secondInt * 4.0);
self->secondBar.frame = secondFrame;
}
}
- (void)swapFrames
{
hourFrame = self->hourBar.frame;
minuteFrame = self->minuteBar.frame;
secondFrame = self->secondBar.frame;
}
I separated the code so that just before the view appear it should update the bars. However, it did not work. I did some investigating by printing out the values of some of the variables at certain points. It appears that in viewWillAppear, secondBar.frame (and minuteBar, etc.) has updated to the correct height. However, in viewDidAppear, that value is reset to 0. This does not happen to secondInt, or secondFrame. Somewhere between those two methods the frame is reset but I cannot figure it out.
From what I understand, the frames for your properties self.hourBar, self.minuteBar and self.secondBar are set to 0 when you switch between tabs, and only update them every second.
If this is indeed the case, just set them to their correct values in your viewControllers viewWillAppear: method (assign them to some property in viewWillDisappear:).
As a sidenote, you seem to be coming from C++. The "->" notation is very uncommon for Objective-C, since properties are accessed with ".", and their corresponding instance variable with "->". Using the arrow notation will not call the auto-synthesised getter/setter methods of properties!
Also, is there a specific reason why you always create new NSTimer objects instead of setting repeats: to yes? Creating a timer and adding it to a runloop (which scheduledTimerWith:... does) is a relatively costly operation.

Resources