I have a MainViewController and by using prepareforsegue I pass data to my NowPlayingViewController. When I select audio in the MainView everything I need to be pushed is pushing successfully to the NowPlayingViewController, but after going back from the NowPLayingViewController to the MainViewController I have no way of accessing the NowPlayingViewController without selecting a new audio file. From what I understand, when using storyboarding and segues, it automatically creates a new instance of the view. So my question is, how would I have a button on my MainViewController that could access the last instance of NowPlayingViewController?
try overriding - (void)willMoveToParentViewController:(UIViewController *)parent in your NowPlayingViewController.
I'm not use to story board and segue so I might be off the track.
Have you try keeping a pointer to your NowPlayingViewController in your MainViewController? Or a pointer to your player? You could store it before pushing your NowPlayingViewController on the UIViewController presentation stack so you would always have the more recent one.
Related
I have a Navigation app. The root view controller (RootViewController) has a button that navigates to another view controller (DetailViewController1). It is very easy to do it in XCode storyboard.
My problem is : DetailViewController1 always create a new instance when I navigate to it. While I tried another way, I created another DetailViewController2 class and create its instance when the app start. Then I write code to push the DetailViewController2 instance, in this case, the DetailViewController2 is only be created once.
The question is : Is there a setting on storyboard so that I can prevent creating the same view controller instance when navigating to it? Just like I push the manually created DetailViewController2.
No, there isn't. The only way to push always the same instance is to perform the push from code, as you have already done.
Set a story board id for viewcontroller . Then in button Action
myViewController* vc=[self.storyboard instantiateViewControllerWithIdentifier:#"storyboardid"];
[self.navigationController pushViewController:vc animated:YES];
I have problem with calling methods from one UIViewController by another UIViewController.
Currently I have UIScroll view with two UIViewControllers.
I want to change something in second one and see results in first one.
I try to do this in this way:
Inside function of second UIViewController:
-(void)doSomething:(){
FirsOneViewController *firstVC = [FirsOneViewController alloc] init];
[firstVC changeUnits:0];
}
Function is called but I don't se any changes in first controller.
BR,
Paul
From your code I see you create a new instance of FirstViewController and so there is no reason why the current instance inside the scrollview would receive this message.
You need to send the changeUnits: message to the current FirstViewController, so you need a reference to it. To do this you may want to think about creating a protocol, so that you parent container (the scrollview) is notified by the SecondViewController and then notifies the FirstViewController. A simpler(and lazier) solution is make the SecondViewController have a strong reference to the FirstViewController (though this solution may bite you in the future).
As said in other answers you are creating a new instance of FirsOneViewController instead of referencing to the one you already have.
Here are three ways of doing what you are asking:
Delegation:
The FirstViewController should be the delegate of the SecondViewController (as the secondViewController is calling methods on the FirstViewController). You should tell the SecondViewController that the FirstViewController is its delegate in what ever class initialises the two viewControllers.
From what you have said so far this seems like your best option.
NSNotification:
This could be good option if you think more than one object will want to listen to the change in the SecondViewController. Just post an NSNotification in the SecondViewController and add an NSNotification listener in the FirstViewController
Singleton:
if there should only ever be one instance of the FirstViewController in existence then make it a singleton. By making a class initialiser method. so that you can create/get the current instance of the object from anywhere in your appellation.
Hope this helped.
I'm using SWRevealViewController in my app (to get the slide out side panel) however whenever the user navigates to another viewController like 'settings' and comes back, everything gets reset. I understand this is normal behaviour for storyboards since a new VC is instantiated and viewDidLoad is called each time. I tried to get around this by storing the VC in an array in the AppDelegate and then going back to the original viewController, this prevented viewDidLoad being called when the original VC is initially re-presented but I still found it get's called randomly when moving between veiwcontroller's, resetting all my properties etc.. On researching, the Apple documentation does say not to assume viewDidLoad will only be called once.
Is this behaviour apparent in UITabBarController when switching tabs as I'm thinking of ditching the SWRevealViewController and using that instead if it's going to be less headache.
Should I be handling this differently, ie. storing the 'state' in NSUserDefaults and restoring on viewDidLoad?
Thanks in advance.
viewDidLoad is called exactly once, when the UIViewController is first loaded into memory. This is where you want to instantiate any instance variables and build any UIViews that live for the entire lifecycle of this UIViewController.
In UITabBarController also the viewdidLoad for UIViewController is called once, when you are switching tabs.
viewDidLoad() method is called only once. Its an integral part of the cycle.
It is called then the respective UIViewController class is loaded into memory.
And yes, if you want to initialise any properties or access and modify the NSUserDefaults, it can and should be done in the viewDidLoad method.
As for your app, whenever the user will switch between different UIViewControllers, the viewDidLoad method will be called for every destination UIViewController.
Also, as correctly pointed out, it'll also be called in the case of a memory warning.
I may go mad very soon.
This is the reason:
- I started up with Single View Application project with storyboards. Then I set the view controller class name in the storyboard for my viewController.
- Next step I created one pointer for this viewController in AppDelegate method ...didFinishLaunchingWithOpt... and filled it up by calling [myStoryboards instantiate...]. It works pretty good because I can call method like [vc1 setMyName] which does smthng like self.myName = #"Johnny";
- But here it comes. When I create IBAction method joined with button, this method doesn't know anything about "Johhny". And this is because I'm in another instance. When I check the address of "self" it is another one...
WhyWhyWhy??? Please help, how can I use still the same object - the one instantiated in AppDelegate by storyboards and the one from storyboards in "interface builder".
Thank you.
Oh my. I think I really underestamated it...
When we were talking about getting pointer of other viewControllers from storyboard...
I have initialViewController got by calling rootViewContr... And another one connected with segue (modal) where is UITableView. A get data on rootViewController and I want to show them on the other one in the list (UITableView). So I call segue (performSegueWithIdentifier), the other controller is shown but the list is clear. Because the method I call is working with tableView variable which is null :/ Because, again, I'm in another object. That is because I call that method storyboard instantiate... How can I get exactly the same viewController which I'm working in storyboard with. It is quite confusing for me :/
I read something about prepareForSegue and getting the pointer by destinationViewController but that is not what exactly I want. I need the pointer before I call segue method and the viewController is shown...
Thank you.
If you've set up your initial view controller properly in the storyboard, you don't need to assign it to the windows rootViewController property in -applicationDidFinishLaunchingWithOptions: as this is done for you automatically. It sounds like you're creating a second instance. To access the original instance setup by the storyboard simply do this in -applicationDidFinishLaunchingWithOptions:
InitialViewController *viewController = (InitialViewController *)self.window.rootViewController;
viewController.myName = #"Johnny";
I am new to iOS and wondering how to properly implement view controller unloading/reloading.
Right now my app has a NavigationController with a MainMenuViewController (custom view controller) set up as root view controller. During the course of app lifetime, new ViewControllers are pushed/popped on the Navigation Controller. This works fine, the appropriate ViewControllers are initiated (from NIBs) the first time they are pushed to the stack.
However, I now want to unload one particular ViewController when it is popped, then reload it automatically when it is pushed again.
I have added a [self release] to that ViewControllers viewDidDisappear: and it unloads, but when i try to push the view again, i get a message sent to dealloc'ed instance error and crash. Therefore, my questions are:
Is that a proper way to unload a popped ViewController?
How to check if a given ViewController is loaded or not?
How to force a reload? With loadWithNib:, then push onto navigation stack?
Regards,
Peter
Welcome to iOS programming. Your crash is a memory management issue. It may take you a bit to get the hang of it but memory management gets way easier if you just follow one rule:
an object needs to release anything it retains (alloc is equivalent to retain)
In this case, your view controller is releasing itself and it definitely did not retain itself. Here's how the sequence works with a navigation controller:
The navigation controller is initialized with a root view controller (the first one on its stack). Lets call this firstViewController
A user action tells firstViewController to initialize secondViewController and push it onto the navigation controller. In most cases, firstViewController will release the instance of secondViewController after pushing it. At this point, firstVC is done with secondVC. The navigation controller is now retaining secondVC
User touches the back button on the navigation bar of secondVC. The navigation controller will pop secondVC from the stack and release it. As long as no other object is retaining it, secondVC will get be dealloc'ed.
Now user is back in firstVC. They can do the same user action which will init and push a new instance of secondVC.
Hope that helps a bit.
I'd also recommend you (re)read the Apple docs and look at the sample code referenced in the framework docs.
http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/Introduction/Introduction.html