I have this code (XCode 4, using Storyboards with ARC) which takes data from an array (rArray) and places it in the textfields from which it originally came from (I want to edit the data). The array (rArray) has valid data in it, but nothing is in the textfields. What am I doing wrong?
SingletonListOfReadings *rShareInstance = [SingletonListOfReadings sharedInstance];
rArray *ra = [rShareInstance.listOfReadings objectAtIndex: indexPath.row]; // get an rArray object out of listOfReadings
// place data back into textfields
EnterDataViewController *edvc = [[EnterDataViewController alloc] init];
edvc.txtSTA1.text = ra.rSTA;
edvc.txtBS.text = ra.rBS;
edvc.txtFS.text = ra.rFS;
edvc.txtDesc.text = ra.rDesc;
[self.navigationController pushViewController:edvc animated:YES];
the UI text elements in VC are not yet set when you try to populate it (it will be set only after [self.navigationController pushViewController:edvc animated:YES]; (and only when it gets viewDidLoad).
easy way to go is to change txtSTA1, txtBS, txtFS etc to strings (make sure they are in edvc .h file), pupulate them as u do now
so, txtSTA1STR is a string in the .H file of edvc
and txtSTA is a UI text element in the xib (or programmatically) in edvc
EnterDataViewController *edvc = [[EnterDataViewController alloc] init];
edvc.txtSTA1STR = ra.rSTA;
edvc.txtBSSTR= ra.rBS;
edvc.txtFSSTR= ra.rFS;
edvc.txtDescSTR= ra.rDesc;
[self.navigationController pushViewController:edvc animated:YES];
and inside edvc
- (void)viewDidLoad
{
txtSTA1.text = txtSTA1STR;
//... etc
}
I fixed it... I took the original code and moved it to the View controller (edvc) which handles the objects. Then I called it from the view controller where I needed the data.
Works fine... I think the problem was in the addressing of the receiving textfields.
Thank you for your help... I appreciate it.
Related
I have a problem which is in JTRevealSiderbar's Sidebarviewcontroller , where sidebar button pressed delegate i am calling a code like :
OpeningViewController *controller = [[OpeningViewController alloc] init];
controller.view.backgroundColor = [UIColor clearColor];
//controller.title = (NSString *)object;
controller.leftSidebarViewController = sidebarViewController;
controller.leftSelectedIndexPath = indexPath;
sidebarViewController.sidebarDelegate = controller;
NSArray *viewControllerArray = [[NSArray alloc] initWithObjects:controller, nil];
[self.navigationController setViewControllers:viewControllerArray];
i have checked that from the baseviewcontroller , siderbarviewcontroller and my openingviewcontroller , uinavigationcontroller's memory address is the same.
besides , when i call the code above , OpeningViewController's viewdid load and appear also called without problem.
but here's my problem , view is not shown !? i could not figure out why is this problem.
i have checked that self.navigationController's viewControllers property is null? maybe this is the problem but i also could not figure out why navigationcontroller's viewcontrollers are empty?
someone help me please , any thought will be appreciated! :)
since i am using storyboard and segues , i have created a viewid for my storyboard for each of the viewcontrollers and create each viewcontroller with their storyboard ids . when i implemented this i just needed to give a background image to my each viewcontroller (still i do not know why this happened) . but this solved my problem totally.
if you need any help about this , you can comment on this then i'll pass some codes.
For background: I'm a Windows automation and data translation "expert" (or so they say grins) in my day job. I've been dabbling with Objective-C coding off and on since I bought my first Mac in 2004.
I'm working on an IOS app. My data container class knows how to save and load from disc, and each object responds to an instance method of -(void)saveToImpliedFilename{} or -(void)save:(NSString *)filename {}. There's a static call to load the data files from storage and create distinct data objects from them (they're fairly lightweight objects, so I'm not worried about loading several at a time). The app's domain is such that many of them won't ever be loaded at once anyway.
+(NSArray *)loadData {}
That's all working fine and wonderful. In storage the objects are stored as Xml and life is good.
Where I'm having trouble is when trying to modify the tutorials so that two things happen for me:
Quick note: I'm using the tutorial as a basis for POC coding, then I'll go back and start over with the "real" coding, reusing my data objects and some of the other utility I've built along the way.
Here's my list of goals and the issues:
I want the table view to tell the data objects to save at pretty much every "edit" event. The only one I can consistently get to work is reorganizing the table's order. (the save button and adding a new entry works fine)
entering a new entry into the list creates a nice modal editor with a save and a cancel button which work wonderfully. But if I edit an existing entry, I can't reproduce the save buttons' behaviors. Each time I try, the buttons' events no longer fire. I can't figure out where I'm going wrong.
I'm using the "Editable Table View" project from this tutorial series as my basis: http://www.aboutobjects.com/community/iphone_development_tutorial/tutorial.html
In the following code, the [self isModal] test is where the save/cancel buttons are made visible and wired up. Bringing up the new-entry screen is apparently the only time it's modal. I tried wiring this stuff up so that the buttons were created all the time, but again, the events never fire for either one. The next block below is where the editable table view is called explicitly with the NEW functionality, but the nonModal view of the same tableview is called by the select event on the selector table.
So...
// code snipped for the new/modal editor
- (void)viewDidLoad {
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
// If the user clicked the '+' button in the list view, we're
// creating a new entry rather than modifying an existing one, so
// we're in a modal nav controller. Modal nav controllers don't add
// a back button to the nav bar; instead we'll add Save and
// Cancel buttons.
//
if ([self isModal]) {
UIBarButtonItem *saveButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemSave
target:self
action:#selector(save)];
[[self navigationItem] setRightBarButtonItem:saveButton];
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self
action:#selector(cancel)];
[[self navigationItem] setLeftBarButtonItem:cancelButton];
}
// do stuff here to display my object...
}
// this code is called from the selection table to explicitly add a new data object.
- (void)add {
vhAddVehicleViewController *controller = [[vhAddVehicleViewController alloc] initWithStyle:UITableViewStyleGrouped];
id vehicle = [[Vehicle alloc] init];
[controller setVehicle:vehicle];
[controller setListcontroller:self];
UINavigationController *newNavController = [[UINavigationController alloc] initWithRootViewController:controller];
[[self navigationController] presentViewController:newNavController animated:YES completion:nil];
}
// this is where it's called on the table selection to show the same view without the save/cancel buttons.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
vhAddVehicleViewController *controller = [[vhAddVehicleViewController alloc] initWithStyle:UITableViewStyleGrouped];
NSUInteger index = [indexPath row];
id vehicle = [[self vehicles] objectAtIndex:index];
[controller setVehicle:vehicle];
[controller setTitle:[vehicle Vehiclename]];
[[self navigationController] pushViewController:controller animated:YES];
}
I'm assuming the issue is that presenting it makes it modal, where as pushing it doesn't...? That's fine. But when I take out the test for modal to try to keep the buttons working, no joy. The buttons draw and click when tapped, but the events don't fire.
HALP! :-)
Thanks much.
-- Chris (I logged in with my Google account so at the top of the page I'm showing as "user1820796") shrug
You forgot to call [super viewDidLoad];
Update
Try removing the cancel button that goes on the left side when pushing the view controller. See if save starts working. I think the problem is you should not add a left button to the navigation bar when the view controller is pushed.
Which method signature are you using?
- (void)save
{
NSLog(#"Saving");
}
Or
- (void)save:(id)sender
{
NSLog(#"Saving");
}
I still think this was related to push/popping the view rather than presenting the view. I switched it all to presentation and it's working how I want now.
Thanks for the assistance guys. Quite a different paradigm than I'm used to on the GUI stuff, but I'm getting there.
thanks!
I want to be able to dynamically create ViewControllers based on a JSON file. What I mean is, there will be a json that will dictate how many ViewControllers the user needs. I.e say I have a json file that lays out 5 ViewControllers, I want to be able to dynamically create these ViewControllers and be able to transition between them.
So what I am going to have is JSON file, that sets out the ViewControllers, say 3 for this example. This JSON file has info on the text, buttons etc and how to navigate between them.
So I want to be able to loop through this JSON, and create the necessary view controllers and add the required text, buttons etc. The JSON will also dictate how the view controllers link up together.
I know how to create one VC and add info like this (This is just quick example, just created vc and added label.
UIViewController *vc = [[UIViewController alloc] init];
vc.view.backgroundColor = [UIColor whiteColor];
UILabel *testLabel =[[UILabel alloc] initWithFrame:CGRectMake(220, 50, 130, 80)];
testLabel.backgroundColor = [UIColor clearColor];
testLabel.textColor = [UIColor blackColor];
testLabel.text = #"Hello";;
[vc.view addSubview:testLabel ];
[self.navigationController pushViewController:vc animated:YES];
I don't know how to create several differently named ViewControllers in a loop using JSON. Anyone have any ideas on how to do this? Or is something like this even possible?
Any assistance would be greatly appreciated.
EDIT:
Very basic example of what JSON will look like
{
"ViewControllers":[
{
"name":"FirstVC",
"id":1
},
{
"name":"SecondVC",
"id":2
},
{
"name":"ThirdVC",
"id":3
}
]
}
So first VC links to secondVC and second to thirdVC
Just create an array and hold them there. Something like this:
NSMutableArray *viewControllers = [[NSMutableArray alloc] initWithCapacity:0];
// ...
// Inside a loop
UIViewController *vc = [[UIViewController alloc] init];
vc.view.backgroundColor = [UIColor whiteColor];
UILabel *testLabel =[[UILabel alloc] initWithFrame:CGRectMake(220, 50, 130, 80)];
testLabel.backgroundColor = [UIColor clearColor];
testLabel.textColor = [UIColor blackColor];
testLabel.text = #"Hello";
[viewControllers addObject:vc];
// Release vc and label if you're not using ARC
Now, if you want to name your controllers, one idea would be to create a subclass of UIViewController and add a name (or something like that) property. Then you just set this property also inside your loop and you can refer/filter based on that property.
You won't explicitly name them as separate variables, but rather you may have an NSArray of different UIViewController instances. As you read through your JSON file, you can loop over the information presented, creating a view controller and adding it to the array each time the JSON tells you to. When you're done, you can pull view controllers out of the array as your user navigates back and forth.
What does your JSON look like? Post an example and we may be able to provide more info.
Why your ViewControllers needs different names? You should simply create instance of one viewController class.
For example if you have a 3 "screens" from JSON:
home
second
about
And all of them have different buttons, text etc. And you have a class name MyViewController. This class may have a #property name, #property buttons (probably NSArray with object from your button management class) etc if you want to distinguish your screens.
Next you should store your objects (MyViewController class objects) in NSArray.
So what you want to do when app starts:
You created an object of MyViewController class and display it. If user want to go to second screen you should simply create another instance of the same class.
So if you want to display name of the screen you have a self.name value in your ViewController class.
I have a tableview and a detailview and I can pass data from my tableview to the detail view by including the detail view.h and setting some values from distance with initWithNib.
DetailView *detailView = [[DetailView alloc] initWithNibName:#"DetailView" bundle:[NSBundle mainBundle]];
//passing data gekozenSpel
detailView.gekozenSpel = [tableData objectAtIndex:indexPath.row];
But now I have a data table with multiple entries and one of then is set, that is: can be changed, in the detailview, from 0 to 1 or from 1 to 0, as a string. It works all fine but now I want to apply the change backwards to the table view and that doesn't work.
myTableView *myTableview = [[myTableView alloc] initWithNibName:#"myTableView" bundle:[NSBundle mainBundle]];
[myTableView.theTable replaceObjectAtIndex:location withObject:value];
For if you use an initWithNib way-of-doing then you create a new empty table nsmutablearray. But I want to CHANGE a value in that array at a specific location with a specific content.
Maybe a singleton to access the data from everywhere? I tried but I have to create instances of what I declare as value and then it is private and not public. So I don't understand how you apply a singleton then.
Any help would be appreciated,
Jan
You will need to add a delegate to the DetailView, this delegate will pass a new array to the old view, this array will have the new tableData that you will replece
For more information on the delegate, here are some tutorials
http://www.roostersoftstudios.com/2011/04/12/simple-delegate-tutorial-for-ios-development/
How to use custom delegates in Objective-C
Simple Delegate Example?
I replace in the detail view the property (eigenschap) of the heart symbol (favourite: YES or NO), then that whole array is put over the mother array (dataVoorMijnTabel) to have it updated back into the main table view (mijnTabelView).
[eigenschappendata2 replaceObjectAtIndex:locatiehartje withObject:eigenschaphartje];
mijnTabelView *mtb = [[mijnTabelView alloc] initWithNibName:#"mijnTabelView" bundle:[NSBundle mainBundle]];
mtb.dataVoorMijnTabel = eigenschappendata2;
Any help is appreciated ! It's several days I'm fighting w/o results.
The scenario:
I and iPad application have a SplitViewController that shows 2 controllersViews (Root on the left e Detail on the right)
The Root allows a recursive navigation (tree that could be several drilldown levels) and I'm calling every time the same controller class (UITableView) pushing always in the controller stack). When the user taps a cell (left side), the detail view (right side) shows the information.
Keep in mind that the detail view controller is not always the same class: it means that I'm allocating (and releasing) programmatically several detailView controllers according the kind of information I have to display.
Here the fragment:
UIViewController <ItemGenericViewController> *newDetailViewController = [[NSClassFromString(cntrClass) alloc] initWithNibName:cntrXib bundle:nil];
//the detailViewController has been defined in the head section as ItemGenericViewController
//each detailViewController is a subclass of ItemGenericViewController
detailViewController = newDetailViewController;
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:detailViewController];
// Update the split view controller's view controllers array.
NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, nav, nil];
self.splitViewController.viewControllers = viewControllers;
[nav release];
[viewControllers release];
[detailViewController release];
Everything is working fine until a memory warning arises.
From that moment if I try to display a new detailViewcontroller the "connection" in the SplitViewController, between the RootController and the detailController, seems vanished. The result is: nothing appear on the right part of the splitController.
In the mean time if I navigate to parent level in the root controller the situation still failing.
For your information each time I push in the stack a new RootController instance (left column) I'm releasing the same controller (to save memory as usual) and I suspect, after receiving the memory warning, iOS is trying to free itself memory and my "history" disappear and the related connection, throught the split controller, too.
Is a nightmare ;-)
Do you have any suggestion ?
Thanks
Dario
I had a similar problem to you (maybe even worse - 16 combinations of possible view switches)... But I believe i have solved it right now.
So, i believe you have used Apple's example for view switching (I have, with modifications), and if you have so, problem is that "root" splitViewController (from MainWindow.xib) get's "niled" as default behavior when memory warning. And even if you add new array of view controllers to it, it will not cause any change (and even worse, it will not show any sign of warning). And solution is to check is it nil, and if is, to reinitialize it.
here is the code, using example from above:
UIViewController <ItemGenericViewController> *newDetailViewController = [[NSClassFromString(cntrClass) alloc] initWithNibName:cntrXib bundle:nil];
//the detailViewController has been defined in the head section as ItemGenericViewController
//each detailViewController is a subclass of ItemGenericViewController
detailViewController = newDetailViewController;
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:detailViewController];
// Update the split view controller's view controllers array.
NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, nav, nil];
/**** Milos Edit ****/
if (self.splitViewController == nil) {
// I'm keeping reference in app delegate, but any way to reinitialize splitViewController is OK
self.splitViewController = delegate.splitViewController;
}
/**** end of edit ****/
self.splitViewController.viewControllers = viewControllers;
[nav release];
[viewControllers release];
[detailViewController release];
Hope it will be helpful.
Cheers
Milos