send image between views using prepareForSegue - objective-c

I am working on an Iphone application using storyboard.
I have a button in a view (SelectionViewController) and when the user clicks on the button, it goes to another view (ImagesResultsViewController) (.
What I need is to send an image from the first view to the second. for that I named the segue identifier "resultViewSegue" and used the prepareForSeague method to get reference to the destination view and place the image in a UIImage view on it:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
//if the segue identifier is "resultViewSegue"
if([segue.identifier isEqualToString:#"resultViewSegue"])
{
//get the destination view which is ImagesResultsViewController
ImagesResultsViewController * destinationView = segue.destinationViewController;
//Set the image in the UIImageView
[destinationView.mainImageView setImage:myImageToSend];
//mainImageView is a UIImageView in the "ImagesResultsViewController" I created a property for it and synthesize it
}
}
However the image was not set. after debugging I found out that the destinationView.mainImageView is null. How can I get a reference of the UIImageView and set its picture from the segue?
Thank a lot for any help

create a UIImage property in the ImagesResultsViewController
In the prepareForSegue method set it to the image you want and then in the viewdidload
set it in the UIImageView

Related

error while loading xib file from tableview in ios

i am trying to make an app in which i use tableview.
I am populating the tableview and i am able to display data in the table. Now what i am trying to do is when i click a specific cell in the tableview i want to load a particular xib file in different folder. For all other cell i want to load second tableview. i am using a storyboard.
i am using
(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([((UITableViewCell *)sender).textLabel.text isEqualToString:#"ABCD"]) {
ABCD *abcdViewController = [[ABCD alloc] initWithNibName:#"ABCD" bundle:nil];
// Push the view controller.
[self.navigationController pushViewController:ABCDViewController animated:YES];
}
// Pass the selected object to the new view controller.
NSLog(#"%#", ((UITableViewCell *)sender).textLabel.text);
MethodsViewController *methodsViewController = segue.destinationViewController;
NSString *rowTitle = ((UITableViewCell *)sender).textLabel.text;
NSDictionary *selected = [[self methodsDict] objectForKey:rowTitle];
methodsViewController.rows = [selected objectForKey:#"rows"];
methodsViewController.methodsDict = [selected objectForKey:#"methodsDict"];
}
This is the code i am using. i made this code after searching the internet.
but the problem is
but when i build and run this the first tableview is shown and when i click on the ABCD cell the xib loads but the navigation bar is covering the upper portion of the xib file and when i click on the back button in the navigation bar it takes me to the black blank page and shows a error
nested push animation can result in corrupted navigation bar
Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
and the app stops
I dont know what i am doing wrong i am new to ios
I hope you understand my problem
Thanks in advance
You have at least three possible approaches to what you are trying to do.
The easiest one is using shouldPerformSegueWithIdentifier: to control exactly when segueing as specified in IB and when pushing your ABCD view controller instead:
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender{
if ([((UITableViewCell *)sender).textLabel.text isEqualToString:#"ABCD"]) {
ABCD *abcdViewController = [[ABCD alloc] initWithNibName:#"ABCD" bundle:nil];
// Push the view controller.
[self.navigationController pushViewController:ABCDViewController animated:YES];
return NO;
}
return YES;
}
This should work pretty easily for you, since it is similar to what you have been trying to do with prepareForSegue:. The fault with your current approach using prepareForSegue: is that you are both pushing your ABCD controller and doing the segue. shouldPerformSegueWithIdentifier: allows you to cancel the segue, so to say, when you are going to push manually.
Another approach would be using manual segues:
you can create a manual segue in IB by dragging from the view controller (as opposed to dragging from the prototype table cell); you can create multiple named segues;
in your table view delegate you override tableView:didSelectRowAtIndexPath: so that it calls performSegueWithIdentifier::
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *identifierOfSegueToCall;
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:nowIndex];
if ([cell.textLabel.text isEqualToString:#"ABCD"]) {
identifierOfSegueToCall = #"ABCDSegueIdentifier";
} else {
identifierOfSegueToCall = #"XYWZCellSegueIdentifier";
}
[self performSegueWithIdentifier:identifierOfSegueToCall sender:self];
}
Finally, a third approach would be defining two different cell prototypes for your table view and segueing from each prototype cell into the appropriate view controller. This is similar to what you have already done for setting up your current segue, only you should add a new prototype cell and define a specific segue from it.

Perform segue from main view on container view

I seem to be unable to understand how to go about this. I have a button on my main view. This view contains a container view. I would like the button on the main view to make the container view segue to another view. I have set up an identifier for the segue, which goes from containerView1 to containerView2. This is a push-segue. The identifier is pushSegue.
On the button on the main view I have tried this:
- (IBAction)btnChangeLocation:(UIButton *)sender {
UIViewController *a = [[ContainerView1 alloc]init];
[a performSegueWithIdentifier:#"pushSegue" sender:nil];
}
I have successfully performed this segue from within containerView1, by just placing within it, and performing the segue from there. It works just fine then.
- (IBAction)testButton:(UIButton *)sender {
[self performSegueWithIdentifier:#"pushSegue" sender:nil];
}
But how would I go if I wanted to trigger the segue on the containerView1, from the button on the main view?
Thanks.
EDIT:
I would also like to be able to perform the same segue, from a container view, that is within the container view.
Just to summarize.
MainView----->ContainerView1-->pushSegue--->ContainerView2
ContaainerView1 has a subContainerView, which also has a button, which causes ContainerView1 to segue into ContainerView2. This button and the button on the MainView does the same thing really, just from different "locations".
EDIT: Added a picture to help explain. http://tinypic.com/r/maxpp2/8
With UIViewController *a = [[ContainerView1 alloc]init]; you are instantiating a new ContainerView1 controller. That won't help you; you need to call performSegueWithIdentifier:sender: on the instance already created.
Depending on how your Storyboard and code are set up, you need to find a way to get a hold of the embedded view controller.
For this set up:
You could do something like this in the main (hosting) view controller:
#property (weak, nonatomic) IBOutlet UIView *childView;
#property (weak,nonatomic) UINavigationController *container;
...
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"embedContainer1"]) {
self.container = segue.destinationViewController;
}
}
-(IBAction)doIt:(id)sender {
[self.container.viewControllers[0] performSegueWithIdentifier:#"pushSegue" sender:nil];
}
By implementing prepareForSegue:sender:, you're able to get a reference to the child viewcontroller; cleaner then going through the array of childViewControllers IMHO.

prepareForSegue not being called from UITableView in a UIViewController

I have a UIViewController that contains a UITableView. The table view contains a custom UITableViewCell. The custom cell was built in interface builder and has a nib. In my main storyboard, I dragged a segue from the custom table view cell to the destination view controller. I set up the bare bones essentials in prepareForSegue, set a break point, but it never gets called.
I'm not that accustomed to using a UITableView in a view controller. I usually use a UITableViewController, but requirements dictate using the table view in a view controller. My initial assumptions is that most methods of doing things would be nearly identical, but I'm finding that not to be the case.
I tried setting the segue from the view controller itself and using didSelectRowAtIndexPath, and though it worked, the transition to the destination view controller was jerky.
Can anyone suggest what I might be missing in order to cause the prepareForSegue method to fire?
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
GaugeViewController *destination = [segue destinationViewController];
[destination setGaugeID:#"1"];
}
Thanks!
You need to refer to the identity of the segue in the Storyboard, something like this:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
GaugeViewController *destination = segue.destinationViewController;
if([segue.identifier isEqualToString:#"yourSegue"]) {
NSLog(#"prepareForSegue called");
[destination setGaugeID:#"1"];
}else {
// do something else
}
}
Also don't forget to set the Identifier in the Storyboard.
Remember that push segues are used with Navigation Controllers and a modal segue can be dragged from view controller to view controller.

How do I use a UISegmentedControl to control UITableView cells?

I've successfully set up a Tab Bar controller with. Table View in the first view and a simple UIView in the second tab. The UIView has it's own class. I've added a segmented control to the latter and ultimately I want to change the images used in the table view cells depending on which segment is selected.
The cell images are part of an array and have been set up using a custom cell.
I've set up the segmented control in the UIView class adding #property an #syntesize but I can't for the life of me figure out how to change the cell images from the UIView class.
Thanks in advance!
The segment control in my UIView.h is defined like so
#property (weak, nonatomic) IBOutlet UISegmentedControl *selectedSegment
I've not yet included an IBAction as I'm not 100% where it would need to go or how it would be written.
In my table view my cell images are currently defined like so in cellForRowAtIndexPath
cell.itemImageView.image = [UIImage imageNamed:[icons objectAtIndex:indexPath.row]];
My thoughts were to put a switch statement within the cell method with each case pointing to a different icon set so
switch (something)
{
case 0:
cell.itemImageView.image = [UIImage imageNamed:[iconSetOne objectAtIndex:indexPath.row]];
break;
case 1:
cell.itemImageView.image = [UIImage imageNamed:[iconSetTwo objectAtIndex:indexPath.row]];
break;
default
break;
}
But I'm pretty sure that's the wrong way of doing it and the "something" bit is what I'm stuck on.
1) In the simple UIView where you have your segmented control:
Define an outlet _tableViewController that you connect to the controller of your table view
Define an action method segmentedControlChanged: that responds to the segmented control being triggered
2) In the table view controller:
Define a property selectedSegmentIndex of type NSInteger
3) Now add the implementation for the action method:
- (void) segmentedControlChanged:(id)sender
{
UISegmentedControl* segmentedControl = (UISegmentedControl*)sender;
_tableViewController.selectedSegmentIndex = segmentedControl.selectedSegmentIndex;
[_tableViewController.tableView reloadData];
}
4) In the table view controller you can now add the switch statement that you suggested to tableView:cellForRowAtIndexPath::
switch (self.selectedSegmentIndex)
{
[...]
}
Note that invoking reloadData in step 3 is a crude way to force the table view to update all cells with the correct images. There are other methods in UITableView that give you more fine-grained control over which cells you want updated (e.g. reloadSections:withRowAnimation:).

Use IBOutlets on different ViewController storyboard

I have a storyboard app with two different ViewController. On the second ViewController I have a UIImageView and I would like to call that UIImageView on the first one. I've been looking for a solution but I can't find anything that work for me.
#property(nonatomic, retain) IBOutlet UIImageView *pic;
I just want to be able to use that UIImageView on the other viewcontroller. I hope you can help me.
EDIT:
yes you can try to set your UIImageView in prepare for segue. I have tried it and it seems to work. You would do it as follows:
**I am assuming that the controller you are seguing to is called NewViewController
**I am also assuming your NewViewController has a UIImageView called imageView
-(void)prepareForSegue....
{
if ([segueIdentifier isEqual....])
{
NewViewController *newController=(NewViewController *)[segue destinationViewController];
[[newViewController imageView]setImage:self.someUIImageFromCurrentClass];
[[newViewController imageView]setNeedDisplay];
}
}
and yes, you do have to create a UIImage in current class (in this case it's self.someUIImageFromCurrentClass). That's the point is that you're taking an image from current ViewController (current class) and showing it in the ViewController you are seguing to.
ORIGINAL:
-(void) prepareForSegue: (UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"your segue name"])
{
[segue.destinationViewController setYourUIImage:self.someImageFromCurrentClass];
}
}
be sure to import the .h file for the controller you're seguing to.
second, YourUIImage is an UIImage that is publicly declared in the controller you're seguing to (like Michael mentioned).
In the destination controller, you'll want to grab that UIImage and set it as the image for you UIImageView:
[self.myImageView setImage:YourUIImage]; // <-- you can do this in ViewDidLoad or ViewWillAppear
that should get you going
**Also I guess it's worth mentioning is that a segue always creates a new instance of the controller you're seguing to, which doesn't exist before the segue, which is why you have to pass the image to it.
You can't use outlets between view controllers (VCs) because there's no automatic one for one VC to refer to another. You'll have to expose public properties or methods that allow the manipulation you need and find some way to pass a reference to one VC from another.
For example, if you pass from one VC to another via a segue, you can manipulate properties in the destination VC from the source in prepareForSegueWithIdentifier:.