textView not getting set from another view controller (using Singleton class) - objective-c

I have a textViewController class. I want to set(basically update) the corresponding textView's content from another view controller which I am pushing over the present textViewController. The way I thought I could do this was to have a shared singleton class and have a string property there to contain the text. I have been using the singleton for storing some other content as well and it worked fine till now.
But the text variable in singleton class doesn't hold the content I pass to it from the second view controller and hence the textViewController, after popping the second view controller, displays the old text even after reappearing. I am updating the textView in its viewWillAppear method which is getting called but shows old text content on NSLogging.
What am I missing here? Please suggest a solution, stuck at it for a long time now.

Declaration
Firstly, declare the NSString in your app delegate .h file. It should look something like this:
//YourAppDelegate.h
#import <UIKit/UIKit.h>
#interface YourAppDelegate : NSObject < UIApplicationDelegate >
{
NSString *sharedString; //WE ADDED THIS
}
#property (nonatomic, retain) NSString *sharedString; //AND THIS
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet SomeViewController *viewController;
#end
Now you want to synthesize the object so that the accessor and mutator methods are made for you. This means you don't have to write the setSharedString: and getSharedString methods - we can simply access and mutate the object by making a reference to it. This is how we synthesize it in the .m file:
//YourAppDelegate.m
#synthesize sharedString;
Assigning a Value
When you want to assign a value to sharedString from another class, you must first retrieve the active instance of your application delegate:
YourAppDelegate *appDelegate = (YourAppDelegate*)[[UIApplication sharedApplication] delegate];
The appDelegate object here is your running app delegate instance. To access the sharedString NSString object in the delegate and assign a value, we'd do this:
appDelegate.sharedString = #"some string we want to assign";
For the duration of our application's runtime, "some string we want to assign" is now stored in sharedString in our app delegate.
Retrieving the Value
You'll want to retrieve the value at some point. To do this, again we'll have to get the running instance of our application delegate:
YourAppDelegate *appDelegate = (YourAppDelegate*)[[UIApplication sharedApplication] delegate];
Once we have the running instance, we can then access the sharedString object stored inside it:
NSString *retrievedString = appDelegate.sharedString;
From this point, retrievedString now holds the value "some string we want to assign".
Note:
Everywhere I mention YourAppDelegate, I am referring to your app delegate - the app delegate you have in your project. It'll be related to your project name (look for the file).

How your NSString property for your Text-Variable is defined? Is it a "weak"?

Related

Objective-C - Call a method that modify a textField from another class

I have two questions :
When I try to call a method from different class (this method modify a textfield after having checked a condition) the method is well called (the NSLog in statutInternet works) but the TextField isn't modified..
When I do it from the (IBAction)internet method it works .. Any solution ?
Why Xcode want me to called my variables (like internetTextfield) with a _ before it ?
WindowsController.h
#import <Cocoa/Cocoa.h>
#interface WindowController : NSWindowController
#property (assign) IBOutlet NSTextField *internetLabel;
- (void)statutInternet;
- (IBAction)internet:(id)sender;
#end
WindowsController.m :
#import "WindowController.h"
#implementation WindowController
- (IBAction)internet:(id)sender;
{
[self statutInternet];
}
- (void)statutInternet;
{
NSLog(#"Callfunctionworks");
if (condition) {
[_internetLabel setStringValue:#"TxtFieldWorks!"];
}
}
I try to call the method statutInternet with this from another class :
WindowController *fenetre = [[WindowController alloc] init];
[fenetre statutInternet];
When I try to call a method from different class it doesn't work:
That's because, You're making another WindowController instance using this code:
WindowController *fenetre = [[WindowController alloc] init];
This is another new separate instance of same class, which I guess you're not showing. So you want to take reference to the window that's already showing rather than making a new instance.
Why Xcode want me to called my variables (like internetTextfield) with a _ before it ?
That's because when you declare variable using #property it does three things:
Makes an internal variable by adding the conventional underscore (_) to the start of the variable name. That's why you've _ as prefix of your variable.
Makes a setter-getter methods.
Takes the keywords you used (ie. assign, strong, weak) in account while implementing the setter-getters.
You can read a good discussion here: #property and retain, assign, copy, nonatomic in Objective-C
The NSTextField (and all of the other UI items) is not created yet when you call statutInternet method.
When your window loaded, your views will be ready :
_fenetre = [[WindowController alloc] initWithWindowNibName:#"WindowController"];
[_fenetre showWindow:_fenetre.window];
[_fenetre statutInternet];

Trying to access a NSTextView from another class

I'm creating a NSTextView in my AppController.h:
#interface AppController : NSObject {
IBOutlet NSTextView *texto;
}
#property (assign) IBOutlet NSTextView *texto;
#end
After connected and properly checked, I'm trying to set a texto for this TextView from another class (AppMenu.m), but with no luck:
#import "AppController.h"
- (IBAction)setText:(id)sender {
AppController *appControl = [[AppController alloc] init];
[[appControl texto] setString:#"Hello"];
}
What should I do?
The problem is that Appmenu creates a new instance of texto, a local one just for appmenu (with the same properties), and not setting properties on the one actually in appcontroller. If you try debugging, you'll see that the two texto objects have different memory pointers.
You could make appcontroller the delegate for appmenu and create a 'setTextoProps' method which can pass data from appmenu over to appcontroller.
You could also make an instance of storyboard.appcontroller and set data directly with something like
Appcontroller *controller = [self.storyboard instantiateViewControllerWithIdentifi er:#"appcontroller"];
[self.controller.texto setText...];
When you call alloc you create a new object. What you need is a reference to the AppController that already exists.
(I'm assuming the text view is already displayed by an AppController object before you execute the code that tries to change its field.)

Access class variable from another class

I have a UITabBarController that manages two ViewControllers. The first is a UIViewController that allows the user to change game settings. The second is a GLKViewController that runs the game simulation.
I'm trying to enable the Game ViewController to fetch the settings from the Settings ViewController. I have a Slider on the Settings View that represents "Speed".
I have a reference to the other controller, but I'm unable to expose the variable that backs my Slider properly.
SecondViewController.h
#interface SecondViewController : UIViewController{
IBOutlet UISlider * mySlider;
}
property (nonatomic,retain) IBOutlet UISlider * mySlider;
#end
SecondViewController.m
- (IBAction) mySliderWasMoved:(id)sender;
#implementation SecondViewController
#synthesize mySlider;
- (IBAction) mySliderWasMoved:(id)sender{
};
ThirdViewController.m
NSArray *tmpVCs = self.parentViewController.tabBarController.viewControllers;
UIViewController *tmpVC = [tmpVCs objectAtIndex:1]; //obtain handle to SecondViewController
//NSNumber *mySpeed = tmpVC.mySlider; //doesn't see mySlider
NSNumber *mySpeed = [tmpVC mySlider]; //doesn't see mySlider
I'm new to this, and there are many aspects of my project to learn - so I'm not trying to learn how to manage data at this time. I just need to know how to access an instance variable
As mention on the comments,
Use NSDefault to save the value on slider changed. On the very first time of loading your application, you will want to set a default value.
Use Singleton Object to store value.
We understand that, quoting from you " not trying to learn data persistence at this time. Nor do I need architecture direction.", but the rule of thumb here is that you probably will be able to access the instance variable in some way or the other but i think having the best approach will benefit you greatly.
Just my 2 cent.
Fort the benefit of others: I grabbed a handle to the other class, but I hadn't declared the return type as the correct type of class.
Replace:
UIViewController *tmpVC = [tmpVCs objectAtIndex:1];
With:
SecondViewController *tmpVC = [tmpVCs objectAtIndex:1];
Now I have access to the properties that are specific to the SecondViewController.

Objective-C Category Return AppDelegate as property

I'm creating an Objective-C category on the UIViewController class. In my project, I want one singular and easy way to get the app delegate.
Here's what I'm doing
// header file UIViewController+AppDelgate.h
#import <UIKit/UIKit.h>
#class ExampleAppDelegate;
#interface UIViewController (AppDelegate)
#property (weak, nonatomic, readonly) ExampleAppDelegate *appDelegate;
#end
// implementation file UIViewController+AppDelegate.m
#import "UIViewController+AppDelegate.h"
#import "ExampleAppDelegate.h"
#implementation UIViewController (AppDelegate)
- (ExampleAppDelegate *) appDelegate {
return (ExampleAppDelegate *)[[UIApplication sharedApplication] delegate];
}
#end
Should I define the property as weak? I think it would be bad to retain this guy as it would normally have retains on view controllers referenced within.
weak/strong in this case is a moot point, since there is no local instance variable holding a pointer. ARC will do the right thing (i.e. it will not send more retains than releases for any given scope).
Why not create a Utility class with a class method that does the same thing, then you can reference it something like:
[Utility appDelegate];
and you wont have to add a property to every single ViewController that needs to access the AppDelegate, the way you currently have it setup.
From the looks of your implementation you dont need to define a property, you only need to declare the method -(ExampleAppDelegate *)appDelegate;
This of course would only work if called on an instance of the class unless you made it a class method.

Why am I getting an error for this?

Why am I getting these errors?
alt text http://img39.imageshack.us/img39/2203/help.tif
It says:
Error: Request for member "jokeTableView" in something not a struction or union
What does that mean? And why is it breaking. I tried reading about initWithStyle but I just could catch up on it
Here is my .h file:
#import <UIKit/UIKit.h>
#interface TableViewController : UITableViewController {
NSMutableArray *jokes;
IBOutlet UITableView *jokeTableView;
}
#property (nonatomic, retain) NSMutableArray *jokes;
#end
Thanks!
Your object (TableViewController) has no property named jokeTableView.
In order to access jokeTableView with the special dot operator, it needs to be a property. Otherwise you have to access it using Key-Value-Coding compliant methods or directly using the -> operator (or just use it as an ivar and no reference to self):
jokeTableView.delegate = self;
or
self->jokeTableView.delegate = self;
or
[self jokeTableView].delegate = self;
or
#property (retain) UITableView *jokeTableView;
// later...
self.jokeTableView.delegate = self;
Also note, however, that you are setting an outlet in the initializer and this won't work. You'll have to set this in the -[TableViewController awakeFromNib] method since self->jokeTableView will be nil when the initializer is actually called (which happens in IB prior to serializing the object into the nib file).
Since you are doing this at init time, the outlets should be NULL, so this initialization shouldn't do anything. This should be done at awakeFromNib time at the earliest.