re-adding a view to the view controller from another class - objective-c

I add a UIView, minimisedInterface, to my view controller as normal
[self.view addSubview:minimisedInterface];
minimisedInterface is removed from the view controller, on a button tap.
[self removeFromSuperview];
I now want to re-add the minimisedInterface to the view controller, but on a button tap in another class, Interface.
What is the correct way to do this? I was considering getting a handle on the view controller from the Interface class but this seems a little counter-intuitive, as if one shouldn't "control" the view controller itself.
Thanks in advance :)

The two likeliest ways that come to mind are:
make the view controller a delegate of the Interface class and have a [delegate presentView]; method (or something of the kind)
send a NSNotification that the view is needed again, from the buttons IBAction, and have the view controller listen for that notification.

Related

Does dismissViewControllerAnimated remove the controller's instance

For my app, I want to have a few different instances of the same view controller. For now, I am just creating a new instance like this:
iSafeViewController *tab = [[iSafeViewController alloc] init];
[tab setModalPresentationStyle:UIModalPresentationFullScreen];
[tab setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self presentViewController:tab animated:YES completion:nil];
Great. And since this is done in the iSafeViewController class anyway, I have another button that currently just dismisses the latest controller on the stack.
- (IBAction)closeTab:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
Okay, however, I really want to be able to go back to these instances. So, I have two questions.
Does dismissViewControllerAnimated remove that controller's instance from memory. If not, is there a way I can re-present it.
There is probably a better way to navigate through viewController instances then presentViewControllerAnimated. At the very least, is there a better way to create new instances of one's viewController and be able to navigate to each of them, hopefully not in a stack. In other words, if there are three viewController instances, is there a way I can go from the third to the main one?
Any ideas would be appreciated. Thanks.
"Does dismissViewControllerAnimated remove that controller's instance from memory? If not, is there a way I can re-present it."
Calling dismissViewControllerAnimated does not explicitly remove a view controller from memory, but if no other part of the code is storing a strong reference to the view controller, once the presenting view controller dismisses your VC, it may be deallocated as per the normal memory management system.
So if you ensure something in your code has a reference to your view controller (aside from the VC which is presenting it modally), it won't disappear after being dismissed, and yes this means you can re-use it.
As for "random access" to view controllers: you could use UINavigationController and use methods like popToViewController:animated: and multiple calls to pushViewController:animated: (without animation!) to create the effect of travelling to arbitrary view controllers. This feels like a bit of a hack.
Alternatively, and preferably, you could write your own custom container view controller. This is a view controller that deals with presenting other view controllers. See Apple docs.
Here's a good WWDC video on the subject: Implementing UIViewController Containment
Further reading:
Container View Controller Examples
http://subjective-objective-c.blogspot.co.uk/2011/08/writing-high-quality-view-controller.html
Custom container view controller

When will viewWill/DidAppear/Disappear is called anyway and how exactly does it work?

I understand that viewWillAppear will be called when duh.... when the the view is about to appear.
But how does IOS know that a controller's view is about to appear?
When exactly that and how it is implemented?
For example, does the childController.view check first that window is one of it's super ancestors? Does the view has a pointer to it's controller? How exactly that works? Does everytime a view is added it check whether it's window is it's super ancestor and whether it is the view outlet of a UIViewController?
For example, if I add childcontroller.view but not to a subview of any view that's being called. Will viewWillAppear called?
Does the childController need to be the a child of a parentController so that viewWillAppear of the childController will be called when the parentController's viewWillAppear is called automatically?
The view is loaded by your controller using the - (void)loadView method. This method is implemented to load a blank view or a view from a nib/storyboard. You only need to override it if you really need to create a view hierarchy from scratch.
All of the magic happens when the value of the view property is first requested and the controller detects the value is nil. All of the life cycle method calls are handled by the UIViewController. There is nothing you need to do other than implement the methods if you need them. Remember one thing: There is no guarantee the view has been loaded until the - (void)viewDidLoad method has been called.
Everything I've learned about controllers how they work has come from the View Controller Programming Guide.

Access Parent View Controller from tableViewController in popover view

I am trying to implement a popover view in a tableview controller. My intention is for the user to select an option from the table list as shown below.
Note that my popover view actually displays the data from a separate table view controller. I am creating the popover view controller via the following initialization method
self.popOverViewController = [[UIPopoverController alloc]initWithContentViewController:optionsTableViewController];
After the user selects an option for example "Hottest All Time", the control should be passed from the tableview Controller (in the popover view) back to the MAIN table view controller (parent view) so as to trigger a table reloadData method.
Query: Is there a way to return the control from the tableview controller in the popover controller back to the MAIN tableview controller?
Do I have to use a delegate method to do this?
The two approaches I've seen are roughly the standard sort of fare:
create a delegate protocol for the class type of optionsTableViewController, have the controller that creates the popover implement it and set itself as the delegate when issuing the popover
use the NSNotificationCenter (which actually fits the intended purpose of the thing if you've a one-to-many message, as may be the case if you've a popover with a setting that affects a bunch of different controllers and you don't really care which is visible when the user requests the popover)

Objective-C: How to send signal from view to view controller to change views?

I have a view controller that controls the switching between views. I would like one of the views to signal the view controller to switch to another view (and can't figure out how I can do this.)
To be more clear (hopefully): My view controller inserts a subview. That subview has a UITableView. I'd like, when you select a row in the UITableView, to remove the current subview and then switch to a different sub-view. Of course, I'd prefer the view controller to continue to keep track of which subview is loaded.
Does this make sense? (I'm still pretty green with Objective-C.)
Is there a way to send the view controller a message from the sub-view (that the view controller created)? Is there another way to accomplish this?
Thanks a bunch for the help... and I'd be happy to clarify if needed.
You might look into setting up a UINavigationController. Use the 2 UIViewControllers to control the individual views, and use the Navigation Controller to switch between the 2 views. From the UITableView, you can simply implement the method -
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
Use this method to alloc the new view controller that you want to display
Then call the Navigation controller to push the new view controller onto the stack -
[self.navigationController pushViewController:controllerName animated:YES]
Finally, release the view controller that has disappeared.
This way the navigation controller keeps track of who is loaded, and can implement convenience functions like animating the transition. Also make sure to lookup the UITableViewController subclass - it is a subclass of UIViewController, but it provides some convenience functions for dealing with tables, like knowing when the user selects a particular row, and allows for the standard edit functions of most iOS apps.

Modal view controllers calling other's "viewDidLoad"

I have a bunch of pages I am chaining together and presenting as modal view controllers. THey all have viewDidLoad methods. It seems that when one is loaded though it calls the viewDidLoad methods of ones in the background too. How can I stop this? Thanks!
You can't. The viewDidLoad method will get called when the view is loaded. Asking a view controller for its view loads the view.
Consider moving code into your viewWillAppear:(BOOL)animated method. That way it will only get called before the view is actually shown to the user.