Custom UIViewController transition with rotation - objective-c

I have a couple of UIViewController subclasses. One that displays a grid and another that is essentially the 'detail view' for the tile on the grid. The user taps a tile and the detail view expands from the grid to fill the screen.
I have managed to get the views to animate properly and can display the content of each view perfectly. My problem comes when the device is rotated. I have displayed the detail view as a subview of the gridview and so when I rotate the device, the grid view controller gets the rotation calls, not the detail view.
As this is a custom animation, I couldn't use the standard pop and push view controller methods. Is there an method that I have to call to make this view controller responsible for handling rotation until it is dismissed?
Thanks

If I understand correctly, you rotate your grid view controller and it responds, but the 'detail view' view controller doesn't change correctly?
If this is the case, there are two possible solutions I can think of (and currently use myself). One solution would be to register the 'detail view' for a notification. Whenever the grid view controller is rotated, send the notification and the 'detail view' should respond as you want it.
The other solution is just a simple check when the 'detail view' is loaded.
if (self.view.bounds.size.height < self.view.bounds.size.width) {
// apply the code you wish to size it for landscape mode;
}
This, of course, would only work if the 'detail view' is not currently visible when the screen is rotated, so sending a notification may be a better choice to cover all possibilities.

You could set up a custom delegate in the grid view controller and register the detail view controller as that delegate after it is set up. In the grid view controller you then implement willRotateToInterfaceOrientation:duration: and didRotateFromInterfaceOrientation: which first call the corresponding methods in the delegate (the detail view controller) and then in super.

Related

How to pan down a view controller in storyboard

I'm using a scroll view in the storyboard for one of my view controllers and I would like to know if there is a way to move the current view of the view controller down so that I can add things below.
I've seen that when tapping on CollectionView (which is at the bottom of my screen and extends below the view), the view on my viewcontroller seems to move down a bit to reveal more of the CollectionView, but not entirely. Is there a way that I can make the view go lower?
Change the size of viewController as shown in the image below:

Custom segue that 'finishes' early?

I'm looking to implement a custom segue that pushes to a UIViewController, but completes before the new UIViewController fully fills the screen, leaving some of the source view controller still in view and functional. (For example; new view controller covers half of the user interface).
I'm keen to use a segue rather than a view that is moved using CGRect, Quartz framework method, or similar, as constraints get messy really easily, unless a custom segue could utilise such methods(?)
Any pointers greatly welcomed! :)
For this task you would use a container view controller, which manages and displays the content of multiple other view controllers at a time while letting them interact with their views like normal. An example of this would be the UISplitViewController, which displays two view controllers' views at a time, one on each side of the screen. You can design segues that swap out one view controller of the multiple on display in a container view controller, similarly to the Replace Segue implemented by Apple to swap out a UISplitViewController's detail view controller (the one on the right hand side).

Only subviews added in viewDidLoad automatically resize

I've created a custom subclass of UIViewController that acts like a UINavigationController or a UITabBarController. Let's call it a ToolbarNavController. It has a toolbar at the bottom with controls for the user to move to a different content view.
I have two content views aside from the ToolbarNavController's view. Both are loaded from a nib and have their own controllers. The app starts out showing one of them. A button in the toolbar allows the user to switch between them.
When I add these views as subviews of the ToolbarNavController's views in viewDidLoad, they are correctly resized to fill the area between the status bar and the toolbar without overlap/underlap.
But when I try to lazy load the second view, adding it as a subview for the first time only when the user presses the toolbar button, iOS does not resize the view to account for the toolbar in its parent view, and it underlaps the toolbar which messes up my Autolayout constraints. Also, when I don't add the subview in viewDidLoad, if I put the device in landscape orientation before switching to the second view, it loads with a portrait orientation frame.
Bottom line: When inserting a subview in viewDidLoad, iOS sizes it correctly and manages autorotation for it. When inserting it later, I need to detect orientation set the frame myself. (And for some reason when I do this, autorotation kicks in again).
What is going on?
In viewDidLoad, the view is not yet layout for the resolution and interface orientation, and view properties are as they were in the interface designer. So, if you had a portrait view, that is how the initial properties of the view are set when going into viewDidLoad. When you add your view there, you add it to the XIB view. Later, iOS performs layout on the view hierarchy and thus resizes your inserted view as needed. But when adding your view at a later point, the view hierarchy has already been layout, so it is expected that the new view you are adding is also layout correctly.
Best practice is to calculate the size you need using the size of the view you are inserting into. For example, half the width of the containing view, or third the bounds, etc. This way it is independent on the orientation the interface is in.

Background UIViewController loading when ModalViewController is in the foreground (iOS)

I'm not sure why this is happening, but in the App delegate, I'm setting a viewcontroller as the root and presenting a ModalViewController in front of it. The strange thing is that the viewcontroller behind the modalviewcontroller is still loading even though it does not appear. Is this normal? Is there a way to prevent the viewcontroller behind the modalviewcontroller to load?
Thank you
I am not sure exactly what you mean by "loading." As long as the view controller in the background is the parent view controller of the modal view controller, it is going to need be initialized before the modal view controller can be displayed at all. In that sense, it must be loaded.
If, on the other hand, you mean that the contents of the background view controller are visually displayed and then, afterwards, the model view controller appears on top of it—but you don't want the contents of the background controller to be seen until after the modal view controller is dismissed—then one possibility would be to set the hidden property to YES and unhide the contents when modal view controller is dismissed. To do that, I would make the background view controller a delegate of the modal view controller, so it receives a callback when the modal view controller is dismissed.

Programmatically change subviews from within subview's controller

In my iPhone application I've set up a default, blank view called Main View into which various child subviews will be loaded for different parts of the application. It's the same approach as if I was using a tool bar to switch between subviews. That case, in the MainView controller I could hook IBActions to buttons in the toolbar, so that when a button was pressed, MainView added different subviews to itself.
In my situation, though, I need to tell MainView to change its subview from within the subviews. So here are two sister subviews, each with their own controller and xib, that would be loaded as subviews of MainView:
- StartView
- FormView
In StartView, after some animations and welcome stuff, a button triggers the camera image picker. Once the image picker returns the image, I need to tell MainView to remove StartView and add FormView.
It may be the result of a long day or my newness to iPhone OS but I'm stuck getting my head around the right way to set up my objects/controllers.
You never have more than one view controller active at a time. (The nav and tabbar controllers don't control views, they control other controllers.) In this case, you will have a single controller that has the MainView as its view property. It will add StartView and formView as subviews of MainView.
However, this is not a good design. It will overload the MainView controller by forcing it to juggle many views. It would be better to use a hidden navigation controller or a tabbar. Hierarchies of controllers can create the illusion from the users point of view for almost any interface layout you can imagine. There is no need to create a logical structure that mimics the visual one.
From your description you may only need a single view/view-controller pair: Set the formView controller to open the camera view before it displays the formView. When the camera is dismissed it reverts to the formView automatically. No fuss, no muss.