Im trying to build an app where the user inputs a number at a textfield and after pressing the button another view shows up with the result of that input.
Each number th
So it does look like you'll have to to a few things, like use properties and init a singleton to hold the new values. Butt! I'll be showing you what you need to do :)
A singleton is a special kind of class where only one instance of the class exists for the current process. (In the case of an iPhone app, the one instance is shared across the entire app.)
so this will be helpful because you only need to initialize once and use it anywhere in your app, using a prefix file. First lets add that file:
** Adding the Prefix File **
If you still have this folder in your project, Supporting Files, right click on this folder and click Add New File.... Add what's called a PCH File. You might have to look for it in the iOS tab on the left:
After you hit next, name this file Prefix.pch. Be sure you add this file to your target.
Next you'll need to assign this prefix file to your target by:
Project File > Selecting Your Target > Build Settings Tab > Search for 'Prefix Header' and look for the row Prefix Header and double click to enter a value:
The Value you'll be entering in this prefix box is "the containing folder / Prefix.pch. The containing folder is usually the exact name of your project. e.g. My project is named ios-objective-c, therefore i'll be entering ios-objective-c/Prefix.pch; yes i know in my screenshot it's labeled 'overstack-Prefix.pch' :P You just have to make sure they match up :)
Try to Build your project, hit cmd-B :) If an error shows up saying something like this file doesn't exists, that is because you've entered the wrong value in the prefix box
NEXT! is adding your singleton class :)
This one is a lot of copy and pasting, but i'll explain some of it. Ask me anything in the comments and i'll go in depth :)
1.Adding the Files
Add a new Cocoa Touch Class file and call it Library. I put it below the AppDelegate.m. But wherever is good :) The subclass of this will be NSObject. Now this is how you want your new files to look like:
Library.h
#import <Foundation/Foundation.h>
@interface Library : NSObject
//This method, or function, is how you will access this class and all its properties and instant methods. the plus means this method is a class method vs an instant method
+ (Library *)controller;
@end
Library.m
#import "Library.h"
@implementation Library
+ (Library *)controller {
static Library *controller = nil;
if (!controller)
controller = [[Library alloc] init];
return controller;
}
- (id)init {
if (!(self=[super init])) return nil;
return self;
}
@end
Allowing other classes to use this class
Right now no other class can use or call any of these methods, and the last thing you want to do is add import "Library.h"
all over your code! So this is where you'll use the Prefix file:
Prefix.pch
#ifndef ios_objective_c_overstack_Prefix_pch
#define ios_objective_c_overstack_Prefix_pch
// Include any system framework and library headers here that should be included in all compilation units.
// You will also need to set the Prefix Header build setting of one or more of your targets to reference this file.
#import "Library.h"
#endif
Now build again and try to paste this code anywhere in your ViewController class: [Library controller];
Right now it only initializes the singleton, but that's good. Now what you need is to add properties to save to this singleton.
Go back to the Library class and paste this:
Library.h
...
@interface Library : NSObject
@property int inputValue;
+ (Library *)controller;
...
And that is it! There's usually more to properties when you're using object types, like NSString * or NSNumber *. this is what you'd paste for NSNumber *
@property ( nonatomic, retain) NSNumber *inputValue;
You're basically done! If you want to set this value from your view controller:
[[Library controller] setInputValue: <#(int)#>];
And read the value:
[[Library controller] inputValue];
This singleton will save your value all over your app. Hope this answers your question :)
As far as I understand your question, if you need a method returning the string title depending on the number provided you can make your method as a class method of your LibraryData
class, not instance method, like:
+ (NSString *)titleStringFromInt: (NSInteger) intVal {
if (intVal < 5000)
return @"Poor!";
else
return @"Rich!";
}
And call it from your controller like, [LibraryData titleStringFromInt: [[ViewController.fieldLabel text] intValue]]
;
If you need to actually store data into your LibraryData class being accessible from all other controllers in your app, I would suggest taking into singleton pattern implementation.
For example using blocks:
+ (LibraryData *)instance
{
static dispatch_once_t onceToken = 0;
__strong static id _sharedObject = nil;
dispatch_once(&onceToken, ^{
_sharedObject = [[self alloc] init];
});
return _sharedObject;
}
And call it, like [LibraryData instance].number from your ViewController code. Anyway I think it's a good to move your if/else code out of getter method of your variable to some helper class method.
Since Library in this case is acting like your model it is your ViewController's responsibility to set and pull the data from it. The library does not (and should not) know anything about the ViewController class. This is a good solution to the problem you are facing:
So first, you will need a Library instance in your ViewController:
@interface ViewController ()
// Make sure you import library above
@property (strong, nonatomic) Library *library;
@end
Create the actual instance:
- (void)viewDidLoad {
[super viewDidLoad];
self.library = [Library new];
}
Then in your button click you should access your view's text field and set it on the library:
- (IBAction)showResultView:(id)sender {
self.library.number = [[self.fieldLabel text] intValue];
}