How to add up a value when a button pressed - iphone

Last time I have asked how to add up a value when a button is pressed within the method of
-(IBAction)addTap:(id)sender;
now I was taught to use tapCount++; (tapCount is a int type variable) to add 1 everytime the button was pressed.
However, I find that the value stayed the same no matter how many times I pressed it.
I want to make tapCount to be 1 if I press the button once, and make it 2 if I pressed the button twice, and so on.
Can someone tell me how to do this?
Detail:
Lets say I have a class called Player, a member called int tapCount and int result
when each time the button was pressed, a value will be added to tapCount, and the value will be displayed at the end (when the game end lets say)
For now, the value stay the same when I use NSLog to check it.
Player.h
#class TappingViewController;
#interface Player : NSObject {
NSString *name;
int tapCount;
int result;
}
#property (nonatomic, assign) NSString *name;
#property (nonatomic, assign) int tapCount;
#property (nonatomic, assign) int result;
#end
TappingViewController.h
#interface TappingViewController : UIViewController {
}
-(IBAction)addTap:(id)sender;
#end
TappIngViewController.m
#import "TappingViewController.h"
#import "Player.h"
#class Player;
int tapCount;
#implementation TappingViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
/*
- (void)loadView {
}
*/
- (void)viewDidLoad
{
Player *aPlayer = [[Player alloc]init];
NSLog(#"tapCount:%d", aPlayer.tapCount);
[super viewDidLoad];
}
-(IBAction)addTap:(id)sender;
{
NSLog(#"BeforeL %d", tapCount);
tapCount++;
NSLog(#"After: %d", tapCount);
}
/*
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
}
- (void)dealloc {
[super dealloc];
}
#end

In the addTap: method you are referencing the TappingViewController's tapCount which is different to the Player's tapCount, even though they have the same name, they are different. So you need to reference the aPlayer's tapCount property:
aPlayer.tapCount++;
However aPlayer isn't in the addTap: method's scope. The only place you can currently reference aPlayer is in the viewDidLoad method.
This is what you need to change: (you don't need the comments I've added to point out the changes)
TappingViewController.h
#class Player; //**You have imported the Player class in the .m file so if you use the Player class in the header you need to add it as a forward class.
#interface TappingViewController : UIViewController {
Player *aPlayer; //**This is an instance variable (ivar) so you can access it in any method in the implementation (.m file), however you still need to put something in this ivar (see viewDidLoad)**
}
//**You can add a property for aPlayer if you want, but remember to do the memory management properly**
-(IBAction)addTap:(id)sender;
#end
TappIngViewController.m
#import "TappingViewController.h"
#import "Player.h"
//**Get rid of the forward class, as you have imported it above**
//**Get rid of the tapCount that was were**
#implementation TappingViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
/*
- (void)loadView {
}
*/
- (void)viewDidLoad
{
aPlayer = [[Player alloc] init]; //**remove the declaration of a new var**
NSLog(#"tapCount:%d", aPlayer.tapCount);
[super viewDidLoad];
}
-(IBAction)addTap:(id)sender;
{
NSLog(#"BeforeL %d", tapCount);
aPlayer.tapCount++; //**reference the player's tapCount**
NSLog(#"After: %d", tapCount);
}
/*
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
}
- (void)dealloc {
[super dealloc];
}
#end

I really don't feel like you're providing enough information to make it possible for us to tell you what's going wrong. That being said, I might be able to point you in the right direction.
First of all I would suggest that you try the following code:
-(IBAction)addTap:(id)sender {
NSLog(#"Before: %d", tapCount);
tapCount++;
NSLog(#"After: %d", tapCount);
}
I added both of them just to show you that incrementing the variable does indeed work.
If you get output that looks like this:
Before: 0
After: 1
Before: 0
After: 1
Before: 0
After: 1
It means that you set tapCount = 0; over and over again.
If you don't get any output it means that your IBAction isn't connected properly.
If you get the expected output, but it's the same when you "NSLog to check it". It means that you've accidentally run tapCount = 0; again.
Another possibility is that there is something wrong with your NSLog.
If you have any questions feel free to ask.

I assuming the IBAction is in your controller. You will need to add the variable to your header. In the controller for example:
Given that you have the tap counter in another class, your controller needs a pointer to that class.
// controller header file
Player *myPlayer;
// controller implementation file
-(void)awakeFromNib {
myPlayer = [Player alloc] init]; // initialized the player
// do whatever else you need to do
// load previous data from NSUserDefaults, maybe
}
-(IBAction)addTap:(id)sender {
myPlayer.tapCount++;
}

Related

UITextView.text lags when loading text

I want to display text with an UITextView, which is part of an UITabBarView and do so in the following Class:
.h - File:
#import <UIKit/UIKit.h>
#interface DescriptionViewController : UIViewController{
IBOutlet UITextView *descriptionText;
}
#end
.m - File:
#import "DescriptionViewController.h"
#import "Globals.h"
#interface DescriptionViewController ()
#end
#implementation DescriptionViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(void) viewWillAppear:(BOOL)animated{
Globals* myGlobals = [Globals sharedGlobals];
descriptionText.text = [myGlobals.currentLine objectAtIndex:5];
}
#end
When the TextView is displayed the first time it is empty, when i switch to another tab and switch back to the "TextView - Tab" it is displayed properly. But I obviously want it to be displayed correctly the first time..
I already tried to move the relevant code to the -viewDidLoad function, but nothing changed. Also, I tried the -setNeedsDisplay function without success (maybe I used it wrong? - [descriptionText setNeedsDisplay].
I appreciate any help and further code will be posted on request.
Please set breakpoint on ViewWillAppear Method of your class then check that in first time what you are getting from NSLog("%#", [myGlobals.currentLine objectAtIndex:5]);
and you are missing [super viewWillAppear:animated];
try this,
- (void)viewDidLoad
{
[super viewDidLoad];
Globals* myGlobals = [Globals sharedGlobals];
descriptionText.text = [myGlobals.currentLine objectAtIndex:5];
}
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
Globals* myGlobals = [Globals sharedGlobals];
descriptionText.text = [myGlobals.currentLine objectAtIndex:5];
}

make iPhone vibrate programmatically through IF Else statement [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Making the iPhone vibrate
I have two buttons. One button adds up, one button adds down. The question is when I certain number such as lets say 22 is in the text area, the phone vibrates for a certain mount of time. Here is my code for it:
What I am trying to say is IF Label Displays "22" THEN VIBRATE PHONE... The question is how do i go about writing this.. I'm still learning so any help regarding this would be much appreciated! Here is my code so far:
#import "StartCountViewController.h"
#import "AudioToolbox/AudioServices.h"
#implementation StartCountViewController
int Count=0;
-(void)awakeFromNib {
startCount.text = #"0";
}
- (IBAction)addNumber {
if(Count >= 999) return;
NSString *numValue = [[NSString alloc] initWithFormat:#"%d", Count++];
startCount.text = numValue;
[numValue release];
}
- (IBAction)vibrate {
}
- (IBAction)subtractNumber {
if(Count <= -35) return;
NSString *numValue = [[NSString alloc] initWithFormat:#"%d", Count--];
startCount.text = numValue;
[numValue release];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
This is basically a duplicate of Programmatically make the iPhone vibrate
Having said that, I think your code is still going to have errors, and the syntax seems deprecated.
Here's an example. I didn't try this on an actual iphone which would be required to test the vibration, but it should work provided you add the AudioToolbox framework to your project, and of course your XIB file has the necessary connections:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (retain, nonatomic) IBOutlet UILabel *numberLabel;
- (IBAction)addNumber:(id)sender;
- (IBAction)subtractNumber:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#import "AudioToolbox/AudioServices.h"
#interface ViewController ()
{
int count;
}
#end
#implementation ViewController
#synthesize numberLabel;
- (void)viewDidLoad
{
count = 0;
[self updateCount];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[self setNumberLabel:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (void)dealloc
{
[numberLabel release];
[super dealloc];
}
- (IBAction)addNumber:(id)sender
{
if(count >= 999) {
return [self vibrate];
}; // ignore numbers larger than 999
count++;
[self updateCount];
}
- (IBAction)subtractNumber:(id)sender
{
if(count <= -35) {
return [self vibrate];
}; // ignore numbers less than -35
count--;
[self updateCount];
}
-(void)updateCount
{
NSString *countStr = [[NSString alloc] initWithFormat:#"%d",count];
[self.numberLabel setText:countStr];
[countStr release];
}
-(void)vibrate
{
NSLog(#"I'm vibrating");
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}
#end

iPhone application accessing data values from different classes

I have 4 classes i.e views in my application. Class A, having variable a and b.
After clicking on button which is on view A of class A it leads to class B, which is table view controller. Then class B leads to class C. then class C leads to class D.
Now i want to access values of a and b of class A into class D. I tried it with NSNotification but not succeeded.
Please suggest.
I tried with NSNotification:
i tried with NSNotification like Class A---
-(IBAction) selectButton:(id) sender{
NSString * a = [NSString stringWithFormat:#"Manjinder singh"];
NSDictionary * dict = [NSDictionary dictionaryWithObject:a forKey:#"1"];
[[NSNotificationCenter defaultCenter] postNotificationName:#"sendMessage" object:self userInfo:dict];
}
Then Class D----
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(sendMessage:) name:#"sendMessage" object:nil];
}
return self;
}
-(void)sendMessage:(NSNotification *)notification{
A *dil=[[A alloc] init];
nslog(#"dil.a");
NSLog(#"USERINFO:MyUserInfo (its a dictionary):%#",[[notification userInfo] valueForKey:#"1"]);
}
This is the rendom try but basically i want to show variable a and b of class A into class D.
Update:------------
MyCoolViewController.h// a class where data send from
#protocol MyCoolViewDelegate;
#interface MyCoolViewController : UIViewController {
id <MyCoolViewDelegate> delegate;//
}
#property (nonatomic, assign) id delegate;//
#end
#protocol MyCoolViewDelegate <NSObject>//
-(void)sendAStringToAnotherView:(NSString*)string;
#end
MyCoolViewController.m
-(void)viewDidLoad{
[delegate sendAStringToAnotherView:#"this is a string"];
}
firstViewController.m //a class where data sent
-(void)viewDidLoad{
MyCoolViewController *myViewControllerPointer=[[MyCoolViewController alloc] init];
myViewControllerPointer.delegate = self;//
}
-(void)sendAStringToAnotherView:(NSString*)string
{
//displays the string as console output
NSLog(#"plzzzzzz show data",string);
}
value of string is not passed to this class because it is not showing in NSLog output.
UPDATED 2---
MyCoolViewController.m
#import “MyCoolViewController.h”
#import "firstViewController.h"
#implementation MyCoolViewController
#synthesize label1,sttr;
#synthesize delegate;//
-(IBAction) selectButton:(id) sender{
if (curri==nil) {
curri=[[CurrancyViewController alloc] initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:curri animated:YES];
}
curri=nil;
//CHECK ThIS [curri release];
}
- (void)viewDidLoad
{
[delegate sendAStringToAnotherView:#"this is a string"];
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"background1.png"]];
[super viewDidLoad];
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Can you give more context about what specifically you are trying to achieve? It sounds like you want to pass data between several UIViewControllers. Here is how to set up a delegate for one of your view controllers:
#import <UIKit/UIKit.h>
#protocol MyCoolViewControllerDelegate;
#interface MyCoolViewController : UIViewController {
id <MyCoolViewControllerDelegate> delegate;
}
#property (nonatomic, assign) id delegate;
#end
#protocol MyCoolViewControllerDelegate <NSObject>
-(void)sendAStringToAnotherView:(NSString*)string;
#end
Then you will should synthesize the delegate
#synthesize delegate;
and then when you want to pass data to, lets say a parent view, call this function:
[delegate sendAStringToAnotherView:#"this is a string"];
In the other view controller, wherever you instantiated the instance of this UIViewController, you need to set that self as the delegate;
myViewControllerPointer.delegate = self;
and then implement the delegate function in the parent view controller.
-(void)sendAStringToAnotherView:(NSString*)string
{
//displays the string as console output
NSLog(string);
}
The fact that you need communicate between views like this could possibly mean that there is a more efficient means of structuring your app. Can't say for sure without more info.
Try and use this template to add a delegate to your own app.
You could use delegation here
D would become the delegate of A, and when you click the button, A sends a message to D with the variables as arguments and D responds by performing a method.

In Xcode an error says 'activities' undeclared

Hello I'm new to developing and I was wondering if any of you pros would know how to fix this issue.
My code is Below: InstaTwitViewController.m:
#import "InstaTwitViewController.h"
#implementation InstaTwitViewController
/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
*/
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
activities = [[NSArray alloc] initWithObjects:#"sleeping",
#"eating", #"working", #"thinking", #"crying", #"begging",
#"leaving", #"shopping", #"hello worlding", nil];
feelings = [[NSArray alloc] initWithObjects: #"awesome",
#"sad", #"happy", #"ambivalent", #"nauseous", #"psyched",
#"confused", #"hopeful", #"anxious", nil];
}
*/
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[activities release];
[feelings release];
[super dealloc];
}
- (NSInteger)numberOfComponentsInPickerView: (UIPickerView *)
pickerView {
return 2;
}
- (NSInteger)pickerView:(UIPickerView *)
pickerViewnumberOfRowsInComponent :(NSInteger)component {
if (component == 0) {
return [activities count];
}
else {
return [feelings count];
}
}
#end
Next to [activities count] and [activities release] it states an error "'activities' undeclared"
InstaTwitViewController.h:
//
// InstaTwitViewController.h
// InstaTwit
//
// Created by John Bridge on 5/2/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface InstaTwitViewController : UIViewController
<UIPickerViewDataSource, UIPickerViewDelegate> {
NSArray* actvities;
NSArray* feelings;
}
#end
EDIT
You have a typo in your property declaration.
actvities should be activities, with an i.
You should be more careful while coding, and reading your own code...
EDIT END
Apparently, you haven't declared the activities variable. That's why XCode says it's undeclared...
I guess it should be an NSArray... You need to declare the variable in your class interface (the header file).
Something like:
#interface InstaTwitViewController: UIViewController
{
NSArray * activities;
}
#end
Then, in your implementation, you need to allocate it, for instance in the init method:
- ( id )initWithNibName: ( NSString * )nibNameOrNil bundle: ( NSBundle * )nibBundleOrNil
{
if( ( self = [ super initWithNibName: nibNameOrNil bundle: nibBundleOrNil ] ) )
{
activities = [ NSArray new ];
}
return self;
}
And don't forget to release it in the dealloc method:
- ( void )dealloc
{
[ activities release ];
[ super dealloc ];
}
Remove the /* and */ code before and after the viewDidLoad method, and declare an NSArray called activities in your .h file.
NSArray *activities;
EDIT---- As MacMade said, just fix the spelling mistake!

How to hide variables for distributed code

So I've built a few apps and am now trying my hand at building a piece of iPhone code that others can drop into their applications. Question is how do I hide the data elements in an object class header file (.h) from the user?
For example, not sure if people have used the medialets iPhone analytics but their .h does not have any data elements defined. It looks like:
#import <UIKit/UIKit.h>
#class CLLocationManager;
#class CLLocation;
#interface FlurryAPI : NSObject {
}
//miscellaneous function calls
#end
With that header file, they also supply an assembly file (.a) that has some data elements in it. How do they maintain those data elements across the life span of the object without declaring them in the .h file?
I am not sure if it matters but the .h file is only used to create a singleton object, not multiple objects of the same class (FlurryAPI).
Any help would be much appreciated. Thanks
Take a look at this:
Hide instance variable from header file in Objective C
In my header file I'd have:
#interface PublicClass : NSObject
{
}
- (void)theInt;
#end
In my source file I'd have:
#interface PrivateClass : PublicClass
{
int theInt;
}
- (id)initPrivate;
#end;
#implementation PublicClass
- (int)theInt
{
return 0; // this won't get called
}
- (id)init
{
[self release];
self = [[PrivateClass alloc] initPrivate];
return self;
}
- (id)initPrivate
{
if ((self = [super init]))
{
}
return self;
}
#end
#implementation PrivateClass
- (int)theInt
{
return theInt; // this will get called
}
- (id)initPrivate
{
if ((self = [super initPrivate]))
{
theInt = 666;
}
return self;
}
#end
I'm using theInt as an example. Add other variables to suit your taste.
I recommend you to use categories to hide methods.
.h
#import <Foundation/Foundation.h>
#interface EncapsulationObject : NSObject {
#private
int value;
NSNumber *num;
}
- (void)display;
#end
.m
#import "EncapsulationObject.h"
#interface EncapsulationObject()
#property (nonatomic) int value;
#property (nonatomic, retain) NSNumber *num;
#end
#implementation EncapsulationObject
#synthesize value;
#synthesize num;
- (id)init {
if ((self == [super init])) {
value = 0;
num = [[NSNumber alloc] initWithInt:10];
}
return self;
}
- (void)display {
NSLog(#"%d, %#", value, num);
}
- (void)dealloc {
[num release];
[super dealloc];
}
#end
You can't access to the private instance variables via dot notation, but you can still get the value by using [anObject num], though the compiler will generate a warning. This is why our apps can get rejected by Apple by calling PRIVATE APIs.