how to change an uilabel from another class - iphone

I have my ViewController.h/m and another class Keyboard.h/m.
In my ViewController.h I have an UILabel:
#interface ViewController : UIViewController{
UILabel *label;
}
#property (nonatomic, retain) IBOutlet UILabel *label;
and my ViewController.m looks so
#import "ViewController.h"
#synthesize label;
...
Now I want to change the label from Keyboard.m.
I have tried something like this:
#import "ViewController.h"
...
ViewController *vc;
vc.label.text = #"text";
it compiles without any errors but the label doesn't change

It's very error prone that you're doing here.
ViewController *vc;
declares a pointer, but this won't be initialized; so when you're accessing its property vc.label.text, objc_messageSend() will be passed a bogus pointer, so it can potentially crash! (you're lucky if id didn't do so.)
Anyways: if you have done it well, like ViewController *vc = [[ViewController alloc] init]; creating a new instance wouldn't have affected the other instance. You have to store the pointer to your instance somewhere, e. g. set a #property (retain) ViewContrller *vc; to your application's app delegate object, and access it through that property like this:
[(MyAppDelegate *)[[UIApplication sharedApplication] delegate] vc].label.text = #"new text";
that way it should work.
Hope it helps.

How are you initiating your vc variable? I am guessing that is where the error is coming from. Try doing:
vc = [[ViewController alloc] initWithNibName:# ViewController"];
If you are already doing that, make sure your IBOutlet is hooked up correctly. You are setting the variable correctly so the error must be coming from somewhere else.

Related

arc with navigation delegate error property delegate not found on object of type viewcontroller

I'm hoping someone can shed some light on my question below.
I'm getting a property delegate not found on object of type viewcontroller error on when I declare the delegate in the parent view:
Here's the relevant code in the parent .h file:
#protocol ModalViewDelegate
- (void)didReceiveFrequencyMessage:(NSString *)message;
#end
#interface jhsManageRemindersViewController : UIViewController<UIAlertViewDelegate, UINavigationControllerDelegate, ModalViewDelegate>
and here's where I call the child view:
jhsScheduleViewController *jhsScheduleController = [[jhsScheduleViewController alloc]
initWithNibName:#"jhsScheduleViewControllerr" bundle:nil];
jhsScheduleController.delegate = self;
// Create the navigation controller and present it modally.
UINavigationController *navigationController = [[UINavigationController alloc]
initWithRootViewController:jhsScheduleController];
navigationController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:navigationController animated:YES];
and here's part of my child .h file
#protocol ModalViewDelegate ;
#interface jhsScheduleViewController : UIViewController {
//id<ModalViewDelegate> delegate;
// __unsafe_unretained id <ModalViewDelegate> _delegate;
__weak id <ModalViewDelegate> delegate;
NSMutableString *message;
}
#property ( weak) id<ModalViewDelegate> delegate;
//#property (nonatomic, weak) id<ModalViewDelegate> delegate;
#property (nonatomic, retain) NSMutableString *message;
and finally, here's my .m usage
#synthesize delegate;
//#synthesize delegate = _delegate;
I've viewed and tried various solutions based upon Stackoverflow questions and this recommended blogpost. I've included some of my attempted solutions in commented out code, just as an FYI.
I started with the code I had in an iOS4 app but that generates the error. As a footnote, this is an app with a TabBarController and a NavigationController
Can someone tell me how to fix this so the delegate error can be resolved?
Thank you for your help!
Well, I'm not sure what the problem was. But as a last resort, I saved every file, then tried to build it, with Xcode still reporting the error, which worked.
Actually, there was an error in the initWithNibName but it ran fine until it got to that point, and correcting the typo fixed that. Again, I'm not sure what the problem was but I seem to be on my way.

Difficulty accessing objects in another view controller

I'm setting a string in a view controller called ViewController and trying to access it somewhere else. This is the code:
ViewController.h
NSString *string;
...
#property (retain) NSString *string;
ViewController.m
#synthesize string;
...
-(void)viewDidLoad {
...
string = #"Test";
}
OtherViewController.m
#import "ViewController.h"
...
-(void)viewDidLoad {
ViewController *vc;
vc = [[ViewController alloc] init];
NSLog(#"String: %#", vc.string);
}
However, the log is showing: String: (null). What am I doing incorrectly? Thanks.
The viewDidLoad of ViewController is only called when the view is loaded. The view is lazily loaded when required e.g. when a call to vc.view is made.
I'm not sure what you are trying to achieve but this certainly seems like a code smell to me.
As #Fscheidl points out you are creating a new instance and not accessing an existing instance so this may add to your problem. I still believe your main issue is that you assume viewDidLoad is being called just by creating the viewController, which is not the case
edit : it doesn't necessarily need to be an NSObject class, if you want to, you could also do this on your viewController class, just be sure to also include
-(id)init
on your header
---- end of edit
if you're trying to make a class that's accessible to another view controller, why not try NSObject instead of view controller (considering you only need to take that string value)
for instance, lets call that viewController class "global" class
so at global.h, you put up
#import <Foundation/Foundation.h>
#interface GlobalVar : NSObject
#property (nonatomic, strong) NSString *myString;
-(id)init;
#end
and then, at global.m you put up
#import "GlobalVar.h"
#implementation GlobalVar
#synthesize myString;
-(id)init
{
self = [super init];
if(self)
{
myString = [[NSString alloc]initWithFormat:#"the String"];
}
return self;
}
#end
after this, everytime you need to access the "myString" object that contained in global class, you could put up
at header :
#import "GlobalVar.h"
...
...
#property (nonatomic, strong) GlobalVar *globalVar;
at implementation file :
#synthesize globalVar;
...
...
self.globalVar = [[GlobalVar alloc]init];
NSString *theString = globalVar.myString;
NSLog(#"content of my string is : %#",theString);
there you go ;)
You do create a new instance of ViewController by calling [[ViewController alloc] init]; This instance hasn't had string even set. You have to access that exact instance of ViewController.
If you create the instance of OtherViewController directly from ViewController, you can add the following to OtherViewController.h:
#import "ViewController.h"
#property (nonatomic, retain) ViewController *previousViewController
When creating the OtherViewController, you can then set:
//alloc and init instance of OtherViewController
myOtherViewController.previousViewController = self;
In your viewDidLoad: method, you can then access your string as follows:
NSLog(#"String: %#", previousViewController.string);

Pass variable to another view

I'm trying to set a variable in another view.
I'm in a view which I have named ProgramViewController and from here I would like to set a variable named bands in MyViewController.
I thought it would be as simple as
MyViewController *myViewController = [[MyViewController alloc] init];
myViewController.bands = #"hello world";
[myViewController release];
And in the header of MyViewController:
#interface MyViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
NSString *bands;
}
#property (nonatomic, retain) NSString *bands;
That does not work, though.
Can anyone please tell me what I am doing wrong?
EDIT:
I synthesize bands in MyViewController:
#synthesize pageNumberLabel, tableProgram, bands;
But when trying to print it with NSLog in the viewDidLoad of MyViewController I get (null)
NSLog(#"%#", bands);
You need to synthesize the bands variable in MyViewController.m
#synthesize bands;
A variable needs to be synthesize in order to use it as a public property outsize of a class in Objective-C
I solved this in another way. I managed to load the data in MyViewController instead. I was dealing with a page controller and had to populate a UITableView but had troubles loading the data.
This is solved in a completely other way now.

Objective-c Novice - Needs help with UIViews

Im new to iphone development and after lots of reading on it im still trying to figure out how UIViews operate properly. I have been playing about with it and i this is where i am at so far:
I have created a new xcode project using the view-based application. I have my MMAppViewController classes and i created a new UIViewController subclass called "Level1View".
There is a button titled "Level 1" that takes me to the "Level1View" viewController. In this viewController there is there is a "next" button, a "main menu" button (that returns to MMAppViewController) and there is a label, currently titled "Level 1".
My problem is that the code i have used to change the title of label does not work! Does anyone know why this is? Here is my code:
#class MMAppViewController;
#interface MMAppAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
MMAppViewController *viewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet MMAppViewController *viewController;
#end
and
#implementation MMAppViewController
-(IBAction)pushLevel1{
Level1View *level1View = [[Level1View alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:level1View animated:YES];
}
...
and
#import <UIKit/UIKit.h>
#interface Level1View : UIViewController {
IBOutlet UILabel *labelTitle;
}
-(IBAction)pushBack;
-(IBAction)pushNext;
#end
and
#import "Level1View.h"
#import "MMAppViewController.h"
#implementation Level1View
-(IBAction)pushBack{
MMAppViewController *MainView = [[MMAppViewController alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:MainView animated:YES];
}
-(IBAction)pushNext{
[labelTitle setText:(#"Thanks for playing :)")];
}
- (void)didReceiveMemoryWarning {
...
Currently the app runs but the label wont change when i hit the "next" button. Can anyone help?
are you sure a UINavigationController isn't a better tool for the job you want to do? That will make it easy for you to manage a stack of UIView objects.
That said, have you tried adding logging to make sure your pushNext method is getting called? where is labelTitle declared? Did you use a XIB or not?
Did you bind the Label in Interface Builder to the labelTitle outlet in your Level1View?
If you forget that step, the outlets won't work. Even after several years, I still forget this step sometimes.
--Mike
are you sure you connected the label in IB?
and if you set a property "#property (nonatomic, retain) IBOutlet UILabel *labelTitle;" in Level1View.h you can access it from Main View:
Level1View *level1View = [[Level1View alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:level1View animated:YES];
level1View.labelTitle.text = #"something";
[level1View release];
The other thing you shouldn't present the Main View Controller again instead dismiss the Level1View with:
#implementation Level1View
-(IBAction)pushBack{
[self dismissModalViewControllerAnimated:YES];
}
//
and maybe the problem is [[Level1View alloc] initWithNibName:nil bundle:nil] you have to specify the nib you want to load e.g. [[Level1View alloc] initWithNibName:#"Level1View" bundle:nil]
Declare labelTitle as a property in your header file, and synthesize labelTitle in your .m - as long as labelTitle is hooked up through interface builder the rest of your code is fine.
.h
#property (nonatomic, retain) IBOutlet UILabel *labelTitle;
.m
#synthesize labelTitle;
Then your setter call will work. (also, dot-notation works for synthesized properties so you may as well use it)
change
[labelTitle setText:(#"Thanks for playing :)")];
to
labelTitle.text = #"Thanks for playing :)";
Synthesizing a property will create setter and getter methods at runtime. Read: The Objective-C Programming Language

How can I update my view controller's UILabel through another class?

I'm my class i've added a an instance of my view controller, created a property and then synthesized it in my implementation file. I am trying to update the UIlabel in the view controller like this,
NSString *currentChar = [[NSString alloc] initWithFormat:#"%c", ch];
viewController.outputLabel.text = currentChar;
[currentChar release];
My problem is that everything builds without any errors or warnings but the label just doesn't get updated, what am I doing wrong. I'd really appreciate some help on this one.
Are you sure you're referencing the existing viewController and you didn't instantiate a new one? Your property is not declared as copy, correct?
textProcessor.h / .m
#interface textProcessor : NSObject {
MainViewController *mainView;
}
#property (retain) MainViewController *mainView;
#end
#implementation textProcessor;
#synthesize mainView;
MainViewController.h / .m
#interface MainViewController : UIViewController {
UILabel *myLabel;
}
#property (retain) UILabel myLabel;
#end
#implementation MainViewController
#synthesize myLabel;
When you are initializing your textProcessor class, and you set the value for "mainView" like
-(void)viewDidLoad {
[super viewDidLoad];
textProcessor *proc = [[textProcessor alloc] init];
proc.mainView = self;
//note that you are not doing this:
//MainViewController *mainView = [[MainViewController alloc] init];
//proc.mainView = mainView;
//that was creating a new instance variable instead of using self, the existing one
[textProcessor release];
}
Have you created your label in IB? If you are using IB you have to create an IBOutlet for your UILabel. You then make a connection between the UILabel in IB to your IBOutlet in your class.
Have you tried calling the setNeedsDisplay method on the view? Also you may want to try using the setText method instead of assigning directly to the property.