How to pass a variable between two view in iOS - objective-c

As you see in the tile I try to share a variable between two views (the id of the selected object).
How can I do?
Here is my code for put on my other view :
EditProd *edit = [[EditProd alloc] initWithNibName:#"EditProd" bundle:[NSBundle mainBundle]];
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:edit animated:YES];
[edit release];
And which code I need in my other view to get this variable?

EditProd should have a public property e.g.
#property bool myBooleanVariable;
Then just change it from view1 e.g.
EditProd *edit = [[EditProd alloc] initWithNibName:#"EditProd" bundle:[NSBundle mainBundle]];
edit.myBooleanVariable = false;
[self.navigationController pushViewController:edit animated:YES];
[edit release];

Declare a property on your second view controller (EditProd), and then set that property before calling pushViewController.

You can do it three different ways:
add a property to the new view and write to it from the first view
add protocol with method, that can take this variable, set the delegate to the first view, access from new view
save variable into some object, which is accessible from both views

Related

How to addsubview to a view on class1 from class2?

I'm trying to do a really simple thing - I've got a main Xib file for the whole app and another Xib file for a small view.
I want the small view (Xib called "additionalView.xib") to appear in the first Xib ("ViewController.xib").
I have succeeded to do so in the "ViewController.m" but I want more - I want to do it from "additionalView.m"
There is a method I created called "openView:" in "additionalView.m" and it looks like this:
-(IBAction)openView:(id)sender
{
ViewController *vc = [[ViewController alloc] init];
NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:#"additionalView" owner:self options:nil];
UIView *nibView = [nibObjects objectAtIndex:0];
[vc.view addSubview:nibView];
}
The method is being called and the lines are being read by the debugger - but nothing happens.
No crash - No error - No small view in bigger view.
Why is that?
I know that the last line is probably what's
screwing everything up but i don't know how to put it correctly.
Your problem is that ViewController *vc = [[ViewController alloc] init]; creates a new view controller. Because it's new, it's not the one that already exists in the view controller hierarchy that's managing the display.
Your method needs to access the existing view controller. How it does that depends on your app's structure and which object has a reference to the original controller object.
Try
[self.view addView:view.vc];
However, I'm not sure what is you view structure here. You say your -(IBAction)openView:(id)sender is in your "additionalView.m", but it is not the main view controller, correct? You need to do this in the main controller, so basically move the openView: method to your ViewController.m
And you normally need a separate view controller for each view to keep things neat and separate, so the additionalView.m should be an instance of UIViewController, which you can then create from your main view as follows:
-(IBAction)openView:(id)sender
{
AdditionalView *vc = [[AdditionalView alloc] initWithNibName:#"additionalView"];
[self.view vc.view];
}
You have options ... First you don't need to create a view controller vc if you just need the view . Create a uiview and add it .
Option 1: pass a ref to the app vc as suggested above and then :
[appVC.view addsubview:additionalView]
This will add it to main.
Use a view controller manager / ref in the app delegate that you can refer to as delegate and add your view to the current showing view.
Hope this helps

passing data iOS nsmutable array

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;

UIPopOverController inside UISplitViewController

I have to show one popOver inside the left side of one splitController, I initialize the popOver whit an navigationController. But when i show the popOver my app crash.
Impostazioni *settings = [[Impostazioni alloc] initWithStyle:UITableViewStyleGrouped];
settings.title = NSLocalizedString(#"SETTINGS", nil);
settings.contentSizeForViewInPopover = kContentSizeOfPopOver;
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:settings];
nav.navigationBar.tintColor = kTintColorNavigationBar;
nav.contentSizeForViewInPopover = kContentSizeOfPopOver;
UIPopoverController *popOver = [[UIPopoverController alloc] initWithContentViewController:nav];
[popOver presentPopoverFromBarButtonItem:self.navigationItem.rightBarButtonItem permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
This is my code. Any ideas?
EDIT: Crash even if I set only a viewController instead of SplitController :/ And with a empty ViewController :/
(Possibly duplicate of Error using UIPopoverController.)
In short, you need to retain the UIPopoverController somehow. Either by defining a property for it or by managing the ref count manually. With ARC, the latter is not an option, so you need to store the reference.
I believe you need an instance variable to hold the popoverController. Otherwise after the method that contains the code that you showed finishes nothing will have retained your popover. Unlike when you add a subview to a view which the view would then retain the subview. The same thing does not take place for popovers.

Switch views on the same tab in a tab bar WITHOUT using a navigation controller

I am looking for a way to switch the current view in a tab container to another, all within the same tab and not using a navigation controller.
I have tried something like this:
FooViewController *fooViewController = [[FooViewController alloc] initWithNibName:#"FooViewController" bundle:nil];
self.view.window.rootViewController.view.window.rootViewController = fooViewController;
[fooViewController release];
And this:
FooViewController *fooViewController = [[FooViewController alloc] initWithNibName:#"FooViewController" bundle:nil];
[self.view removeFromSuperview];
[self.view addSubview:fooViewController.view];
[fooViewController release];
To no avail.
Any ideas?
The method I used was to create a subclass of UIViewController that I used as the root view of 3 child view controllers. Notable properties of the root controller were:
viewControllers - an NSArray of view controllers that I switched between
selectedIndex - index of the selected view controller that was set to 0 on viewLoad. This is nonatomic, so when the setSelectedIndex was called it did all the logic to put that child view controller in place.
selectedViewController - a readonly property so that other classes could determine what was currently being shown
In the setSelectedIndex method you need to use logic similar to:
[self addChildViewController: selectedViewController];
[[self view] addSubview: [selectedViewController view]];
[[self view] setNeedsDisplay];
This worked really well, but because I wanted to use a single navigation controller for the entire application, I decided to use a different approach.
I forgot to mention you will want to clear child view controllers every time you add one, so that you don't stack up a ton of them and waste memory. Before the block above call:
for (UIViewController *viewController in [self childViewControllers])
[viewController removeFromParentViewController];

Ensuring that a UIViewController is fully set up before loadView is called

There is a UIViewController that uses a UIImageView, and that image view is initialized with image data (NSData). It does not use a XIB, but creates its view programmatically:
- (void)loadView
{
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageWithData:self.imageData]];
scrollView = [[UIScrollView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
scrollView.contentSize = imageView.bounds.size;
scrollView.delegate = self;
[scrollView addSubview:scrollView];
}
That data has to be set by another controller which allocs, inits, and pushes this view controller onto the navigation controller:
ImageViewController *imageViewController = [ImageViewController alloc] init];
imageViewController.imageData = someData;
[self.navigationController pushViewController:imageViewController animated:YES];
How do I know that everything that needs to be done, which in this case, is setting the data, is done before loadView is called? Or, do I not know, and I have to create a custom initializer, or somehow call loadView again when the view controller receives the data?
I have faced many similar situations where I was confused about what will happen, such as with UITableViewControllers.
How do I know that everything that needs to be done, which in this case, is setting the data, is done before loadView is called?
Because the documentation mentions that view controllers do not load their views until they are needed. And the view controller's view is not needed before the navigation controller tries to push it on screen.
Besides, the proper place for assigning the imageData to your image view is probably viewDidLoad ("If you want to perform any additional initialization of your views, do so in the viewDidLoad method."). And your loadView method will not do anything visible in its current form. You have to assign a view to the view controller's view property in that method.
loadView will happen when the view property of the view controller is accessed. The code you wrote will work fine, because the first time the view property will be accessed will be somewhere inside pushViewController.
If you wrote this you'd have a problem:
ImageViewController *imageViewController = [ImageViewController alloc] init];
NSLog(#"size = (%.0f, %.0f)", imageViewController.view.frame.size.width,
imageViewController.view.frame.size.height);
imageViewController.imageData = someData;
[self.navigationController pushViewController:imageViewController animated:YES];
because you access the view property in the NSLog. That would cause loadView to get called before imageData was set.