Accessing parentViewController's variables - iphone

I want to allow a pushed to set parentViewController's instance variables. For instance, VC1 (the parent) has a bunch of textfields and what not which are filled from VC2 (the child). VC2 is pushed onto the stack by VC1. I've tried doing like parentViewController.myString = "foo"; however since parentViewController is a UIViewController, I can't edit the myString field.
Basically, my question is "How can I access the parent's instance variables?"
Edit: I tried the solution here: Setting property value of parent viewcontroller class from child viewcontroller? but it is chocked full of syntax errors.

Have the parent view controller subclass UIViewController (e.g. ParentViewController), implement all the properties for instance variables you wish to manipulate, and set the variables as ((ParentViewController *)parentViewController).myString = #"foo";.
E.g.
#interface ParentViewController : UIViewController {
NSString *myString;
}
#property (nonatomic, retain) NSString *myString;
#end
and
#implementation ParentViewController
#synthesize myString;
#end

Related

Accessing viewController properties from the app delegate

I am quite new to iOS programming so please be nice :) I am trying to google out this for hours now with no success. I have setup an iOS master detail project.
What i need to do. is to change a label in the detailViewController when the app calls applicationDidEnterBackground
This is my faulty code in the appdelegate applicationDidEnterBackground method
UIViewController *temp = [self.navigationController visibleViewController];
NSLog(#"%#",[temp nibName]);
if ([temp nibName] == #"DetailViewController") {
temp._lblBrewingTime = #"";
}
This doesnt work. semantic issue: lblbrewingtime not found on object of type UIViewController.
If I add a breakpoint and check the structure of the temp pointer. I can see the _lblBrewingTime type.
Can you please point me how to get the properties of whatever view is currently loaded in the app delegate?
thank you very much,
Greets,
Nick
You have to explicitly cast it to DetailViewController, once you are sure that the visibleViewController is DetailViewController actually.
So here's the fix:-
UIViewController *temp = [self.navigationController visibleViewController];
NSLog(#"%#",[temp nibName]);
if ([temp nibName] == #"DetailViewController") {
DetailViewController* tempDVCObj = (DetailViewController*)temp;
//temp._lblBrewingTime = #"";
tempDVCObj._lblBrewingTime = #"";
}
And it says absolutely correct that your property _lblBrewingTime is not the property of UIViewController, it's the property of DetailViewController i.e. a subclass of UIViewController.
Some things here:
You should keep a reference to your main controller in the AppDelegate and access the view through this reference - the visible view controller in the navigation controller may not be your view controller class, e.g. because you navigated to another view.
You access the view controller via the UIViewController interface. The UIViewController class does not know about your child view controller's properties, so it cannot access the _lblBrewingType. You have to use your view controller's class name to access its properties, e.g. MyViewController * myVc = (MyViewController*)viewController.
_lblBrewingType looks like an internal variable of your view controller. To access it from the outside, you must provide it as a property:
// MyViewController.h
#interface MyViewController : UIViewController
{
UILabel* _lblBrewingType;
}
#property (strong, nonatomic) IBOutlet UILabel *lblBrewingType;
And the implementation:
// MyViewController.m
#implementation MyViewController
#synthesize lblBrewingType;
#end

How to add Connection Outlets from separate class file (.m) Objects to ViewController's MainStoryboard

I want to maintain data encapsulation and have separated an NSObject class (.h and .m file) from my ViewController.m.
I have the Objective-C working correctly where my class is instantiated in the ViewController's viewDidLoad and I can set, get and NSLog the private values via my NSObject's methods.
What I can't do is in the MainStoryboard assign the Connection Outlets and Received Actions. My IBOutlets (a UILabel and UIButton) aren't showing in the Connection Inspector. However, I have many Objects in my ViewController's .[hm] file that I can setup the Outlet Connections to. It's just this new file's Objects that I can't view in the storyboard tool.
What am I doing wrong?
// GameTimer.h
#import <Foundation/Foundation.h>
#interface GameTimer : NSObject {
UILabel *gameTimerLabel;
NSTimer *gameTimer;
unsigned int gameTimerTicks;
}
#property unsigned int gameTimerTicks;
#property (nonatomic, retain) IBOutlet UILabel *gameTimerLabel;
#property (nonatomic, retain) IBOutlet UIButton *startButton;
// instantiate the timer
- (IBAction)onStartPressed:(id)sender;
// Update the gameTimerLabel, show new value to user
- (void)gameTimerShow;
// selector func for our timer, manages the tick count for all our timers
- (void)gameTimerEvent;
#end
// FirstViewController.m
#import "FirstViewController.h"
#import "GameTimer.h"
#interface FirstViewController ()
#end
#implementation FirstViewController
GameTimer *myGameClock;
- (void)viewDidLoad
{
[super viewDidLoad];
myGameClock = [[GameTimer alloc] init];
[myGameClock setGameTimerTicks:33*10];
[myGameClock gameTimerShow];
unsigned long myticks = myGameClock.gameTimerTicks;
NSLog(#"Ticks=%lu", myticks);
}
I think you may be confusing encapsulation the role of a controller. Since the Cocoa Touch framework is a Model-View-Controller, the Controller is the "manager" that sits between the View's user interpretation and the Model's data and business rules. Therefore you must put your IBOutlets and IBActions in your UIViewController subclasses.
Build your timer into a separate class. The timer would then be considered part of the model that other controllers or other objects of the model can instantiate as needed. Let your Controller instantiate a "Timer". Then use the Controller to manage the "Timer" operations. If you need to display the elapsed time, then the Controller should get the elapsed time from the "Timer" object and put it in the appropriate control. If you need to set the length of time in the "Timer" then the Controller will get the value from a View's control and put it in the "Timer".
Hope this helps

How to get UITextField String from ViewController to NSObject

Hi i am trying to pass the value from my UITextfield that is declared and being used in my ViewController over to an NSObject I have created that needs the value in it to perform an operation. I'm just not sure what I have to do, I have tried this
I have declared the UITextField in my ViewControllers header file and created an IBOutlet for it.
Then I have #imported this into my NSObject and tried to call it like this
NSString *tempTextField = regTextField.text;
and its getting a error 'regTextField not defined'.
If regTextField is defined in your ViewController subclass, then you probably want to set the text field in your NSObject from your view controller. I would import your NSObject into the view controller and then have an NSString property in your NSObject that you can set from the viewController.
myClass.fieldIWantToSet = self.regTextField.text;
Hope this helps.

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.

How return a value from view2 to view1 when using navigation bar

I am New to the iPhone Development. How can i carry a string value from view2 to view1 when using navigation bar. I have no problem in carrying string values from view1 to view2 to view3 to....by using pushviewcontroller But when i come back to previous views using Back button of navigation bar, I cannot able to hold string values.
I need your help in solving this issue.
Thanks In Advance
This thing can be done easily if the pass the reference of the current class to the next class and change the values by using this reference.
Like:
The class that is to be pushed.
#interface B:UIViewController{
id delegate;
}
#property (nonatomic,retain) id delegate;
#end
#implementation B
#synthesize delegate;
-(void)methodA{
[delegate setNewString2:#"Madhup"];
}
#end
The class from which you are pushing B:
#interface A:UIViewController{
NSString *newString;
}
#property (nonatomic,retain) NSString *newString;
#end
#implementation A
#synthesize newString
- (void)method2{
B *newBObject = .......;
[newBObject setDelegate:self];
[self.navigationController pushViewCo.......];
}
#end
Hope this helps.
There's more than one way to do this. Here are a few:
You can access all the view controllers in the navigation stack via the navigation controller's viewControllers property: self.navigationController.viewControllers
You can reach the previous view controller (i.e. the one that pushed the current controller onto the navigation stack) via the parentViewController property: self.parentViewController
You can use the delegate pattern, where the previous (parent) view controller would be the current (child) controller's delegate.
You can keep a reference (retain) to the child controller in the parent controller.
In the first 3, the child controller would be responsible for handing the data to the parent controller. In the 4th, the parent would get the data from the child before releasing it.