I have two view controllers on iOS app.
The first view controller (A), store a table view with cells of data.
When i select a cell, i use the follow method for go to second view controller (B):
if (secondViewController == nil) {
secondViewController = [[SecondViewController alloc] initWithNibName: #"nibName" bundle:nil];
}
[self.view addSubview:secondViewController.view];
When i am in the second view controller (B) and i want come back to first view controller (A) i use the method:
[self.view removeFromSuperview];
And then i come back to first view controller (A).
The problem is:
When i select a different cell in the first view controller (A) i go to the second view controller (B) but this time, with the same data of the previous cell.
The view controller doesnt refresh data automatically...
I tried use the viewWillAppear, but it didnt work so i need a bit help. By the other hand, viewDidAppear doesnt work too of course.
Thanks to all.
The reason it's like that is because you create secondViewController just first time (lazy loading) after that you just add subview:
if (secondViewController == nil) {
secondViewController = [[SecondViewController alloc] initWithNibName: #"nibName" bundle:nil];
}
You can sort it out by doing:
secondViewController = [[SecondViewController alloc] initWithNibName: #"nibName" bundle:nil];
[self.view addSubview:secondViewController.view];
But where do you load the data to your subview. If you want to change the view depending on data you should do something like that:
if (secondViewController == nil) {
secondViewController = [[SecondViewController alloc] initWithNibName: #"nibName" bundle:nil];
}
//Pass some data here
secondViewController.SOMEDATA = YOURDATA;
[self.view addSubview:secondViewController.view];
[viewThatYouWantToRefresh setNeedsDisplay];
or if you need to update the data in the cells on the UITableView:
[tableView reloadData];
I am sure I understood you correctly but I think you can change
if (secondViewController == nil) {
secondViewController = [[SecondViewController alloc] initWithNibName: #"nibName" bundle:nil];
}
to
secondViewController = [[SecondViewController alloc] initWithNibName: #"nibName" bundle:nil];
So you will recreate SecondViewController each time you choose new cell.
Just remove this condition:
if (secondViewController == nil)
i.e no need to check if secondViewController is nil or not. The problem is you are creating secondViewController only once.
Related
I have been getting this same error all day and I understand that it is saying that the segue is not identified in storyboard, but it is. Below is the code I believe is relevant:
1.IBAction for the button that is signaling for the segue.
-(IBAction)launchScanner:(id)sender{
NSLog(#"launch Scanner pressed");
[self performSegueWithIdentifier:#"launchScanner" sender:self];
}
This is the prepare for segue function, I've left it empty for now, not sure if I need to include something in it.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([[segue identifier] isEqualToString:#"launchScanner"]){
}
}
I had originally made everything programatically, here is how I instantiated the Navigation Controller (this is in appdelegate.m):
ViewController *myViewController = [[ViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:myViewController];
_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
_window.rootViewController = navigationController;
[_window makeKeyAndVisible];
Also Here are pictures of my storyboard setup and proof that the segue is identifiedImage 1Image 2
If you want to instantiate your nav controller programmatically, you need to get a reference to it from the storyboard. You can use this if you need to perform some function in the app delegate before loading the initial VC.
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
UINavigationController *initialNavVc = (UINavigationController *)[mainStoryboard instantiateInitialViewController];
self.window.rootViewController = initialNavVc;
There is a mistake in your Storyboard.
Navigation Controller should be "Intial View Controller."
Please check highlight in your image
Here is the solution to tha corrected Storyboard image
I have two view controllers, MainViewController and SecondViewController.
In my main view controller, I have data I pass to the second view controller like so:
-(IBAction)shareToSocial:(id)sender {
SecondViewController *view2 = (SecondViewsController *)[storyboard instantiateViewControllerWithIdentifier:#"PushToNext"];
view2.secTitle = self.MainTitle;
[self.navigationController setModalPresentationStyle: UIModalPresentationCurrentContext];
[self setModalPresentationStyle:UIModalPresentationCurrentContext];
}
Where both secTitle and MainTitle are NSStrings for each controller. From what I've read, by setting view2.secTitle to self.MainTitle, when SecondViewController pops in I my view2.secTitle will have the same value as MainTitle. So if MainTitle is "Hello World" then I open secondViewController, secTitle would also be "Hello World". However, I've been getting null with secTitle even though I am setting the data for it.
If I use pushViewController instead of modal, the values are passed between the two controllers fine. So I'm not sure if I'm doing anything wrong here exactly.
I've also tried using [view2 setSecTitle:MainTitle] to no avail.
There's not much code on my SecondViewController but here's how it looks:
-(IBAction)showMessage:id(sender){
NSLog(#"test: %#", self.secTitle);
}
-(IBAction)closeMessage:id(sender){
[self dismissViewControllerAnimated:YES completion:nil];
}
Also, I've noticed that when I used dismissViewControllerAnimated on SecondViewController to close it and go back to the MainViewController, a black empty screen shows for a few seconds before showing the Main View and touch events on MainViewController is not detected anymore.
Please help.
Could you use performSegueWithIdentifier and prepareForSegue? If you've got your views in your storyboard and set up a segue between them, given it an identifier and set the style to modal you should be able to do this:
-(IBAction)shareToSocial:(id)sender {
[self performSegueWithIdentifier:#"modelToNextSegue" sender:self];
}
Then in prepareForSegue method you pass your values:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
SecondViewController *view2 = [segue destinationViewController];
view2.secTitle = self.MainTitle;
}
Try this:
SecondViewController *view2 = (SecondViewsController *)[storyboard instantiateViewControllerWithIdentifier:#"PushToNext"];
view2.secTitle = self.MainTitle;
UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:view2];
[nav setModalPresentationStyle: UIModalPresentationCurrentContext];
[self setModalPresentationStyle:UIModalPresentationCurrentContext];
I'm using a UIStoryBoard to allow the FirstViewController to add the view of second ViewController as a subview. On removing the sub view using the following method
FirstViewController.m
- (IBAction) btnMoveTo:(id)sender
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"Second"];
vc.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:vc animated:NO];
}
SecondViewController.m
-(void)viewDidLoad{
self.view.opaque = YES;
self.view.backgroundColor = [UIColor clearColor];
}
- (IBAction) withDraw:(id)sender{
[self.view removeWithZoomOutAnimation:2 option:nil];
}
When I access the withDraw Function, the view of the SecondViewController is removed and firstViewController is back. However when I use the button to access the - (IBAction) btnMoveTo:(id)sender function. It doesn't work. Nothing really happens. Any suggestions or help would be greatly appreciated.
You are confusing views with view controllers. View controllers are objects that control views, so for the first line you wrote,
I'm using a UIStoryBoard to allow the FirstViewController to add the view of second ViewController as a subview. On removing the sub view using the following method
you cant add a view controller as a subview of another view controller. You present a view controller that manages its own views, and you can add UIViews as subviews of a UIViewController. A UIViewController manages UIViews.
The problem you are having with the code you posted, is that when you trigger the withDraw: function, you are removing the view of the view controller. Not the view controller itself. You need to dismiss the SecondViewController to gain access of the FirstViewController again.
I've been pulling my hair out trying to get a basic NavigationController working that will allow me to switch back and forth between views easily. I feel like I'm making progress, but I'm clearly missing something critical. I now have my template app pushing views, but only by adding the initWithNibName pointing to the target NIB. Attempting to add any functionality to these secondary views causes the app to crash with a SIGABRT error. I can't imagine this is right.. If I simply have a plain NIB, the switch works fine. The only thing I've added to the secondViewcontroller is a label and a button to populate the label with some garbage text. Yet the instant I hit the switch button to shift push this view i get the SIGABRT. I'd like to be able to put functionality within the different view controllers. I feel like i'm so close, but tis is so aggravating. Can anyone point out where i've gone wrong?
#import "mainViewController.h"
#implementation mainViewController
-(void)switchView {
UIViewController *secondViewController = [[UIViewController alloc] initWithNibName:#"secondViewController" bundle:nil];
secondViewController.title = #"My First View";
[self.navigationController pushViewController:secondViewController animated:YES];
[secondViewController release];
}
-(void)switchViewTwo {
UIViewController *thirdViewController = [[UIViewController alloc] initWithNibName:#"thirdViewController" bundle:nil];
thirdViewController.title = #"My second View";
thirdViewController.view.backgroundColor = [UIColor redColor];
[self.navigationController pushViewController:thirdViewController animated:YES];
[thirdViewController release];
}
Instead of
UIViewController *secondViewController = [[UIViewController alloc] initWithNibName:#"secondViewController" bundle:nil];
Put this:
MySecondViewController *secondViewController = [[MySecondViewController alloc] initWithNibName:#"secondViewController" bundle:nil];
My MySecondViewController should be the name of your UIViewController, also check that the XIB's name is really called secondViewController. Finally:
Go to your XIB
Select the File's Owner file.
Select the 3rd tab in the inspector.
Check the name of the class. It should be MySecondViewController instead of UIViewController.
I have done a sample app with UISplitViewController studying the example they have provided. I have created three detailviews and have configured them to change by the default means. Either using the left/master view in landscape AND using the popover in the portrait orientation.
Now I am trying to move to another view(previous/next) from the currentView by using left/right swipe in each view. For that, what I did was just created a function in the RootViewController. I copy-pasted the same code as that of the tablerow selection used by the popover from the RootViewController. I am calling this function from my current view's controller and is passing the respective index of the view(to be displayed next) from the current view. Function is being called but nothing is happening.
Plz help me OR is anyother way to do it other than this complex step? I am giving the function that I used to change the view.
- (void) rearrangeViews:(int)viewRow
{
UIViewController <SubstitutableDetailViewController> *detailViewController = nil;
if (viewRow == 0) {
DetailViewController *newDetailViewController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
detailViewController = newDetailViewController;
}
if (viewRow == 1) {
SecondDetailViewController *newDetailViewController = [[SecondDetailViewController alloc] initWithNibName:#"SecondDetailView" bundle:nil];
detailViewController = newDetailViewController;
}
if (viewRow == 2) {
ThirdDetailViewController *newDetailViewController = [[ThirdDetailViewController alloc] initWithNibName:#"ThirdDetailView" bundle:nil];
detailViewController = newDetailViewController;
}
// Update the split view controller's view controllers array.
NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailViewController, nil];
splitViewController.viewControllers = viewControllers;
[viewControllers release];
if (rootPopoverButtonItem != nil) {
[detailViewController showRootPopoverButtonItem:self.rootPopoverButtonItem];
}
[detailViewController release];
}
I have googled and found a nice approach. They use a UINavigationController on the detail view to push new views. You could use this same solution for your project.
http://www.cimgf.com/2010/05/24/fixing-the-uisplitviewcontroller-template/